aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/github.com/urfave/cli/command.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/urfave/cli/command.go')
-rw-r--r--vendor/github.com/urfave/cli/command.go304
1 files changed, 304 insertions, 0 deletions
diff --git a/vendor/github.com/urfave/cli/command.go b/vendor/github.com/urfave/cli/command.go
new file mode 100644
index 00000000..23de2944
--- /dev/null
+++ b/vendor/github.com/urfave/cli/command.go
@@ -0,0 +1,304 @@
+package cli
+
+import (
+ "fmt"
+ "io/ioutil"
+ "sort"
+ "strings"
+)
+
+// Command is a subcommand for a cli.App.
+type Command struct {
+ // The name of the command
+ Name string
+ // short name of the command. Typically one character (deprecated, use `Aliases`)
+ ShortName string
+ // A list of aliases for the command
+ Aliases []string
+ // A short description of the usage of this command
+ Usage string
+ // Custom text to show on USAGE section of help
+ UsageText string
+ // A longer explanation of how the command works
+ Description string
+ // A short description of the arguments of this command
+ ArgsUsage string
+ // The category the command is part of
+ Category string
+ // The function to call when checking for bash command completions
+ BashComplete BashCompleteFunc
+ // An action to execute before any sub-subcommands are run, but after the context is ready
+ // If a non-nil error is returned, no sub-subcommands are run
+ Before BeforeFunc
+ // An action to execute after any subcommands are run, but after the subcommand has finished
+ // It is run even if Action() panics
+ After AfterFunc
+ // The function to call when this command is invoked
+ Action interface{}
+ // TODO: replace `Action: interface{}` with `Action: ActionFunc` once some kind
+ // of deprecation period has passed, maybe?
+
+ // Execute this function if a usage error occurs.
+ OnUsageError OnUsageErrorFunc
+ // List of child commands
+ Subcommands Commands
+ // List of flags to parse
+ Flags []Flag
+ // Treat all flags as normal arguments if true
+ SkipFlagParsing bool
+ // Skip argument reordering which attempts to move flags before arguments,
+ // but only works if all flags appear after all arguments. This behavior was
+ // removed n version 2 since it only works under specific conditions so we
+ // backport here by exposing it as an option for compatibility.
+ SkipArgReorder bool
+ // Boolean to hide built-in help command
+ HideHelp bool
+ // Boolean to hide this command from help or completion
+ Hidden bool
+
+ // Full name of command for help, defaults to full command name, including parent commands.
+ HelpName string
+ commandNamePath []string
+
+ // CustomHelpTemplate the text template for the command help topic.
+ // cli.go uses text/template to render templates. You can
+ // render custom help text by setting this variable.
+ CustomHelpTemplate string
+}
+
+type CommandsByName []Command
+
+func (c CommandsByName) Len() int {
+ return len(c)
+}
+
+func (c CommandsByName) Less(i, j int) bool {
+ return c[i].Name < c[j].Name
+}
+
+func (c CommandsByName) Swap(i, j int) {
+ c[i], c[j] = c[j], c[i]
+}
+
+// FullName returns the full name of the command.
+// For subcommands this ensures that parent commands are part of the command path
+func (c Command) FullName() string {
+ if c.commandNamePath == nil {
+ return c.Name
+ }
+ return strings.Join(c.commandNamePath, " ")
+}
+
+// Commands is a slice of Command
+type Commands []Command
+
+// Run invokes the command given the context, parses ctx.Args() to generate command-specific flags
+func (c Command) Run(ctx *Context) (err error) {
+ if len(c.Subcommands) > 0 {
+ return c.startApp(ctx)
+ }
+
+ if !c.HideHelp && (HelpFlag != BoolFlag{}) {
+ // append help to flags
+ c.Flags = append(
+ c.Flags,
+ HelpFlag,
+ )
+ }
+
+ set, err := flagSet(c.Name, c.Flags)
+ if err != nil {
+ return err
+ }
+ set.SetOutput(ioutil.Discard)
+
+ if c.SkipFlagParsing {
+ err = set.Parse(append([]string{"--"}, ctx.Args().Tail()...))
+ } else if !c.SkipArgReorder {
+ firstFlagIndex := -1
+ terminatorIndex := -1
+ for index, arg := range ctx.Args() {
+ if arg == "--" {
+ terminatorIndex = index
+ break
+ } else if arg == "-" {
+ // Do nothing. A dash alone is not really a flag.
+ 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 {
+ err = set.Parse(ctx.Args().Tail())
+ }
+
+ 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)
+ context.Command = c
+ if checkCommandCompletions(context, c.Name) {
+ return nil
+ }
+
+ if err != nil {
+ if c.OnUsageError != nil {
+ err := c.OnUsageError(context, err, false)
+ HandleExitCoder(err)
+ return err
+ }
+ fmt.Fprintln(context.App.Writer, "Incorrect Usage:", err.Error())
+ fmt.Fprintln(context.App.Writer)
+ ShowCommandHelp(context, c.Name)
+ return err
+ }
+
+ if checkCommandHelp(context, c.Name) {
+ return nil
+ }
+
+ if c.After != nil {
+ defer func() {
+ afterErr := c.After(context)
+ if afterErr != nil {
+ HandleExitCoder(err)
+ if err != nil {
+ err = NewMultiError(err, afterErr)
+ } else {
+ err = afterErr
+ }
+ }
+ }()
+ }
+
+ if c.Before != nil {
+ err = c.Before(context)
+ if err != nil {
+ ShowCommandHelp(context, c.Name)
+ HandleExitCoder(err)
+ return err
+ }
+ }
+
+ if c.Action == nil {
+ c.Action = helpSubcommand.Action
+ }
+
+ err = HandleAction(c.Action, context)
+
+ if err != nil {
+ HandleExitCoder(err)
+ }
+ return err
+}
+
+// Names returns the names including short names and aliases.
+func (c Command) Names() []string {
+ names := []string{c.Name}
+
+ if c.ShortName != "" {
+ names = append(names, c.ShortName)
+ }
+
+ return append(names, c.Aliases...)
+}
+
+// HasName returns true if Command.Name or Command.ShortName matches given name
+func (c Command) HasName(name string) bool {
+ for _, n := range c.Names() {
+ if n == name {
+ return true
+ }
+ }
+ return false
+}
+
+func (c Command) startApp(ctx *Context) error {
+ app := NewApp()
+ app.Metadata = ctx.App.Metadata
+ // set the name and usage
+ app.Name = fmt.Sprintf("%s %s", ctx.App.Name, c.Name)
+ if c.HelpName == "" {
+ app.HelpName = c.HelpName
+ } else {
+ app.HelpName = app.Name
+ }
+
+ app.Usage = c.Usage
+ app.Description = c.Description
+ app.ArgsUsage = c.ArgsUsage
+
+ // set CommandNotFound
+ app.CommandNotFound = ctx.App.CommandNotFound
+ app.CustomAppHelpTemplate = c.CustomHelpTemplate
+
+ // set the flags and commands
+ app.Commands = c.Subcommands
+ app.Flags = c.Flags
+ app.HideHelp = c.HideHelp
+
+ app.Version = ctx.App.Version
+ app.HideVersion = ctx.App.HideVersion
+ app.Compiled = ctx.App.Compiled
+ app.Author = ctx.App.Author
+ app.Email = ctx.App.Email
+ app.Writer = ctx.App.Writer
+ app.ErrWriter = ctx.App.ErrWriter
+
+ app.categories = CommandCategories{}
+ for _, command := range c.Subcommands {
+ app.categories = app.categories.AddCommand(command.Category, command)
+ }
+
+ sort.Sort(app.categories)
+
+ // bash completion
+ app.EnableBashCompletion = ctx.App.EnableBashCompletion
+ if c.BashComplete != nil {
+ app.BashComplete = c.BashComplete
+ }
+
+ // set the actions
+ app.Before = c.Before
+ app.After = c.After
+ if c.Action != nil {
+ app.Action = c.Action
+ } else {
+ app.Action = helpSubcommand.Action
+ }
+ app.OnUsageError = c.OnUsageError
+
+ for index, cc := range app.Commands {
+ app.Commands[index].commandNamePath = []string{c.Name, cc.Name}
+ }
+
+ return app.RunAsSubcommand(ctx)
+}
+
+// VisibleFlags returns a slice of the Flags with Hidden=false
+func (c Command) VisibleFlags() []Flag {
+ return visibleFlags(c.Flags)
+}