Update github.com/urfave/cli

It's probably not strictly necessary, but let's work with the current
implementation before worrying about possible idiosyncracies.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
This commit is contained in:
Miloslav Trmač
2018-07-07 00:11:36 +02:00
parent 41d8dd8b80
commit d8f1d4572b
11 changed files with 2345 additions and 822 deletions

View File

@@ -1,4 +1,4 @@
github.com/urfave/cli v1.17.0 github.com/urfave/cli v1.20.0
github.com/kr/pretty v0.1.0 github.com/kr/pretty v0.1.0
github.com/kr/text v0.1.0 github.com/kr/text v0.1.0
github.com/containers/image master github.com/containers/image master

28
vendor/github.com/urfave/cli/LICENSE generated vendored
View File

@@ -1,21 +1,21 @@
Copyright (C) 2013 Jeremy Saenz MIT License
All Rights Reserved.
MIT LICENSE Copyright (c) 2016 Jeremy Saenz & Contributors
Permission is hereby granted, free of charge, to any person obtaining a copy of Permission is hereby granted, free of charge, to any person obtaining a copy
this software and associated documentation files (the "Software"), to deal in of this software and associated documentation files (the "Software"), to deal
the Software without restriction, including without limitation the rights to in the Software without restriction, including without limitation the rights
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
the Software, and to permit persons to whom the Software is furnished to do so, copies of the Software, and to permit persons to whom the Software is
subject to the following conditions: furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

File diff suppressed because it is too large Load Diff

137
vendor/github.com/urfave/cli/app.go generated vendored
View File

@@ -6,23 +6,19 @@ import (
"io/ioutil" "io/ioutil"
"os" "os"
"path/filepath" "path/filepath"
"reflect"
"sort" "sort"
"time" "time"
) )
var ( var (
changeLogURL = "https://github.com/codegangsta/cli/blob/master/CHANGELOG.md" changeLogURL = "https://github.com/urfave/cli/blob/master/CHANGELOG.md"
appActionDeprecationURL = fmt.Sprintf("%s#deprecated-cli-app-action-signature", changeLogURL) appActionDeprecationURL = fmt.Sprintf("%s#deprecated-cli-app-action-signature", changeLogURL)
runAndExitOnErrorDeprecationURL = fmt.Sprintf("%s#deprecated-cli-app-runandexitonerror", changeLogURL) runAndExitOnErrorDeprecationURL = fmt.Sprintf("%s#deprecated-cli-app-runandexitonerror", changeLogURL)
contactSysadmin = "This is an error in the application. Please contact the distributor of this application if this is not you." contactSysadmin = "This is an error in the application. Please contact the distributor of this application if this is not you."
errNonFuncAction = NewExitError("ERROR invalid Action type. "+ errInvalidActionType = NewExitError("ERROR invalid Action type. "+
fmt.Sprintf("Must be a func of type `cli.ActionFunc`. %s", contactSysadmin)+ fmt.Sprintf("Must be `func(*Context`)` or `func(*Context) error). %s", contactSysadmin)+
fmt.Sprintf("See %s", appActionDeprecationURL), 2)
errInvalidActionSignature = NewExitError("ERROR invalid Action signature. "+
fmt.Sprintf("Must be `cli.ActionFunc`. %s", contactSysadmin)+
fmt.Sprintf("See %s", appActionDeprecationURL), 2) fmt.Sprintf("See %s", appActionDeprecationURL), 2)
) )
@@ -41,6 +37,8 @@ type App struct {
ArgsUsage string ArgsUsage string
// Version of the program // Version of the program
Version string Version string
// Description of the program
Description string
// List of commands to execute // List of commands to execute
Commands []Command Commands []Command
// List of flags to parse // List of flags to parse
@@ -61,10 +59,11 @@ type App struct {
// An action to execute after any subcommands are run, but after the subcommand has finished // An action to execute after any subcommands are run, but after the subcommand has finished
// It is run even if Action() panics // It is run even if Action() panics
After AfterFunc After AfterFunc
// The action to execute when no subcommands are specified // The action to execute when no subcommands are specified
// Expects a `cli.ActionFunc` but will accept the *deprecated* signature of `func(*cli.Context) {}`
// *Note*: support for the deprecated `Action` signature will be removed in a future version
Action interface{} Action interface{}
// TODO: replace `Action: interface{}` with `Action: ActionFunc` once some kind
// of deprecation period has passed, maybe?
// Execute this function if the proper command cannot be found // Execute this function if the proper command cannot be found
CommandNotFound CommandNotFoundFunc CommandNotFound CommandNotFoundFunc
@@ -86,6 +85,12 @@ type App struct {
ErrWriter io.Writer ErrWriter io.Writer
// Other custom info // Other custom info
Metadata map[string]interface{} Metadata map[string]interface{}
// Carries a function which returns app specific info.
ExtraInfo func() map[string]string
// CustomAppHelpTemplate the text template for app help topic.
// cli.go uses text/template to render templates. You can
// render custom help text by setting this variable.
CustomAppHelpTemplate string
didSetup bool didSetup bool
} }
@@ -139,13 +144,6 @@ func (a *App) Setup() {
} }
a.Commands = newCmds a.Commands = newCmds
a.categories = CommandCategories{}
for _, command := range a.Commands {
a.categories = a.categories.AddCommand(command.Category, command)
}
sort.Sort(a.categories)
// append help to commands
if a.Command(helpCommand.Name) == nil && !a.HideHelp { if a.Command(helpCommand.Name) == nil && !a.HideHelp {
a.Commands = append(a.Commands, helpCommand) a.Commands = append(a.Commands, helpCommand)
if (HelpFlag != BoolFlag{}) { if (HelpFlag != BoolFlag{}) {
@@ -153,14 +151,23 @@ func (a *App) Setup() {
} }
} }
//append version/help flags
if a.EnableBashCompletion {
a.appendFlag(BashCompletionFlag)
}
if !a.HideVersion { if !a.HideVersion {
a.appendFlag(VersionFlag) a.appendFlag(VersionFlag)
} }
a.categories = CommandCategories{}
for _, command := range a.Commands {
a.categories = a.categories.AddCommand(command.Category, command)
}
sort.Sort(a.categories)
if a.Metadata == nil {
a.Metadata = make(map[string]interface{})
}
if a.Writer == nil {
a.Writer = os.Stdout
}
} }
// Run is the entry point to the cli app. Parses the arguments slice and routes // Run is the entry point to the cli app. Parses the arguments slice and routes
@@ -168,8 +175,20 @@ func (a *App) Setup() {
func (a *App) Run(arguments []string) (err error) { func (a *App) Run(arguments []string) (err error) {
a.Setup() a.Setup()
// handle the completion flag separately from the flagset since
// completion could be attempted after a flag, but before its value was put
// on the command line. this causes the flagset to interpret the completion
// flag name as the value of the flag before it which is undesirable
// note that we can only do this because the shell autocomplete function
// always appends the completion flag at the end of the command
shellComplete, arguments := checkShellCompleteFlag(a, arguments)
// parse flags // parse flags
set := flagSet(a.Name, a.Flags) set, err := flagSet(a.Name, a.Flags)
if err != nil {
return err
}
set.SetOutput(ioutil.Discard) set.SetOutput(ioutil.Discard)
err = set.Parse(arguments[1:]) err = set.Parse(arguments[1:])
nerr := normalizeFlags(a.Flags, set) nerr := normalizeFlags(a.Flags, set)
@@ -179,6 +198,7 @@ func (a *App) Run(arguments []string) (err error) {
ShowAppHelp(context) ShowAppHelp(context)
return nerr return nerr
} }
context.shellComplete = shellComplete
if checkCompletions(context) { if checkCompletions(context) {
return nil return nil
@@ -190,7 +210,7 @@ func (a *App) Run(arguments []string) (err error) {
HandleExitCoder(err) HandleExitCoder(err)
return err return err
} }
fmt.Fprintf(a.Writer, "%s\n\n", "Incorrect Usage.") fmt.Fprintf(a.Writer, "%s %s\n\n", "Incorrect Usage.", err.Error())
ShowAppHelp(context) ShowAppHelp(context)
return err return err
} }
@@ -220,7 +240,6 @@ func (a *App) Run(arguments []string) (err error) {
if a.Before != nil { if a.Before != nil {
beforeErr := a.Before(context) beforeErr := a.Before(context)
if beforeErr != nil { if beforeErr != nil {
fmt.Fprintf(a.Writer, "%v\n\n", beforeErr)
ShowAppHelp(context) ShowAppHelp(context)
HandleExitCoder(beforeErr) HandleExitCoder(beforeErr)
err = beforeErr err = beforeErr
@@ -237,6 +256,10 @@ func (a *App) Run(arguments []string) (err error) {
} }
} }
if a.Action == nil {
a.Action = helpCommand.Action
}
// Run default Action // Run default Action
err = HandleAction(a.Action, context) err = HandleAction(a.Action, context)
@@ -244,11 +267,12 @@ func (a *App) Run(arguments []string) (err error) {
return err return err
} }
// DEPRECATED: Another entry point to the cli app, takes care of passing arguments and error handling // RunAndExitOnError calls .Run() and exits non-zero if an error was returned
//
// Deprecated: instead you should return an error that fulfills cli.ExitCoder
// to cli.App.Run. This will cause the application to exit with the given eror
// code in the cli.ExitCoder
func (a *App) RunAndExitOnError() { func (a *App) RunAndExitOnError() {
fmt.Fprintf(a.errWriter(),
"DEPRECATED cli.App.RunAndExitOnError. %s See %s\n",
contactSysadmin, runAndExitOnErrorDeprecationURL)
if err := a.Run(os.Args); err != nil { if err := a.Run(os.Args); err != nil {
fmt.Fprintln(a.errWriter(), err) fmt.Fprintln(a.errWriter(), err)
OsExiter(1) OsExiter(1)
@@ -277,13 +301,12 @@ func (a *App) RunAsSubcommand(ctx *Context) (err error) {
} }
a.Commands = newCmds a.Commands = newCmds
// append flags // parse flags
if a.EnableBashCompletion { set, err := flagSet(a.Name, a.Flags)
a.appendFlag(BashCompletionFlag) if err != nil {
return err
} }
// parse flags
set := flagSet(a.Name, a.Flags)
set.SetOutput(ioutil.Discard) set.SetOutput(ioutil.Discard)
err = set.Parse(ctx.Args().Tail()) err = set.Parse(ctx.Args().Tail())
nerr := normalizeFlags(a.Flags, set) nerr := normalizeFlags(a.Flags, set)
@@ -310,7 +333,7 @@ func (a *App) RunAsSubcommand(ctx *Context) (err error) {
HandleExitCoder(err) HandleExitCoder(err)
return err return err
} }
fmt.Fprintf(a.Writer, "%s\n\n", "Incorrect Usage.") fmt.Fprintf(a.Writer, "%s %s\n\n", "Incorrect Usage.", err.Error())
ShowSubcommandHelp(context) ShowSubcommandHelp(context)
return err return err
} }
@@ -457,42 +480,18 @@ func (a Author) String() string {
return fmt.Sprintf("%v%v", a.Name, e) return fmt.Sprintf("%v%v", a.Name, e)
} }
// HandleAction uses ✧✧✧reflection✧✧✧ to figure out if the given Action is an // HandleAction attempts to figure out which Action signature was used. If
// ActionFunc, a func with the legacy signature for Action, or some other // it's an ActionFunc or a func with the legacy signature for Action, the func
// invalid thing. If it's an ActionFunc or a func with the legacy signature for // is run!
// Action, the func is run!
func HandleAction(action interface{}, context *Context) (err error) { func HandleAction(action interface{}, context *Context) (err error) {
defer func() { if a, ok := action.(ActionFunc); ok {
if r := recover(); r != nil { return a(context)
switch r.(type) { } else if a, ok := action.(func(*Context) error); ok {
case error: return a(context)
err = r.(error) } else if a, ok := action.(func(*Context)); ok { // deprecated function signature
default: a(context)
err = NewExitError(fmt.Sprintf("ERROR unknown Action error: %v. See %s", r, appActionDeprecationURL), 2)
}
}
}()
if reflect.TypeOf(action).Kind() != reflect.Func {
return errNonFuncAction
}
vals := reflect.ValueOf(action).Call([]reflect.Value{reflect.ValueOf(context)})
if len(vals) == 0 {
fmt.Fprintf(ErrWriter,
"DEPRECATED Action signature. Must be `cli.ActionFunc`. %s See %s\n",
contactSysadmin, appActionDeprecationURL)
return nil return nil
} else {
return errInvalidActionType
} }
if len(vals) > 1 {
return errInvalidActionSignature
}
if retErr, ok := vals[0].Interface().(error); vals[0].IsValid() && ok {
return retErr
}
return err
} }

View File

@@ -12,8 +12,11 @@
// app.Usage = "say a greeting" // app.Usage = "say a greeting"
// app.Action = func(c *cli.Context) error { // app.Action = func(c *cli.Context) error {
// println("Greetings") // println("Greetings")
// return nil
// } // }
// //
// app.Run(os.Args) // app.Run(os.Args)
// } // }
package cli package cli
//go:generate python ./generate-flag-types cli -i flag-types.json -o flag_generated.go

View File

@@ -46,6 +46,11 @@ type Command struct {
Flags []Flag Flags []Flag
// Treat all flags as normal arguments if true // Treat all flags as normal arguments if true
SkipFlagParsing bool 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 // Boolean to hide built-in help command
HideHelp bool HideHelp bool
// Boolean to hide this command from help or completion // Boolean to hide this command from help or completion
@@ -54,6 +59,25 @@ type Command struct {
// Full name of command for help, defaults to full command name, including parent commands. // Full name of command for help, defaults to full command name, including parent commands.
HelpName string HelpName string
commandNamePath []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. // FullName returns the full name of the command.
@@ -82,14 +106,15 @@ func (c Command) Run(ctx *Context) (err error) {
) )
} }
if ctx.App.EnableBashCompletion { set, err := flagSet(c.Name, c.Flags)
c.Flags = append(c.Flags, BashCompletionFlag) if err != nil {
return err
} }
set := flagSet(c.Name, c.Flags)
set.SetOutput(ioutil.Discard) set.SetOutput(ioutil.Discard)
if !c.SkipFlagParsing { if c.SkipFlagParsing {
err = set.Parse(append([]string{"--"}, ctx.Args().Tail()...))
} else if !c.SkipArgReorder {
firstFlagIndex := -1 firstFlagIndex := -1
terminatorIndex := -1 terminatorIndex := -1
for index, arg := range ctx.Args() { for index, arg := range ctx.Args() {
@@ -122,21 +147,7 @@ func (c Command) Run(ctx *Context) (err error) {
err = set.Parse(ctx.Args().Tail()) err = set.Parse(ctx.Args().Tail())
} }
} else { } else {
if c.SkipFlagParsing { err = set.Parse(ctx.Args().Tail())
err = set.Parse(append([]string{"--"}, ctx.Args().Tail()...))
}
}
if err != nil {
if c.OnUsageError != nil {
err := c.OnUsageError(ctx, err, false)
HandleExitCoder(err)
return err
}
fmt.Fprintln(ctx.App.Writer, "Incorrect Usage.")
fmt.Fprintln(ctx.App.Writer)
ShowCommandHelp(ctx, c.Name)
return err
} }
nerr := normalizeFlags(c.Flags, set) nerr := normalizeFlags(c.Flags, set)
@@ -148,11 +159,23 @@ func (c Command) Run(ctx *Context) (err error) {
} }
context := NewContext(ctx.App, set, ctx) context := NewContext(ctx.App, set, ctx)
context.Command = c
if checkCommandCompletions(context, c.Name) { if checkCommandCompletions(context, c.Name) {
return nil 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) { if checkCommandHelp(context, c.Name) {
return nil return nil
} }
@@ -174,15 +197,16 @@ func (c Command) Run(ctx *Context) (err error) {
if c.Before != nil { if c.Before != nil {
err = c.Before(context) err = c.Before(context)
if err != nil { if err != nil {
fmt.Fprintln(ctx.App.Writer, err) ShowCommandHelp(context, c.Name)
fmt.Fprintln(ctx.App.Writer)
ShowCommandHelp(ctx, c.Name)
HandleExitCoder(err) HandleExitCoder(err)
return err return err
} }
} }
context.Command = c if c.Action == nil {
c.Action = helpSubcommand.Action
}
err = HandleAction(c.Action, context) err = HandleAction(c.Action, context)
if err != nil { if err != nil {
@@ -223,14 +247,13 @@ func (c Command) startApp(ctx *Context) error {
app.HelpName = app.Name app.HelpName = app.Name
} }
if c.Description != "" {
app.Usage = c.Description
} else {
app.Usage = c.Usage app.Usage = c.Usage
} app.Description = c.Description
app.ArgsUsage = c.ArgsUsage
// set CommandNotFound // set CommandNotFound
app.CommandNotFound = ctx.App.CommandNotFound app.CommandNotFound = ctx.App.CommandNotFound
app.CustomAppHelpTemplate = c.CustomHelpTemplate
// set the flags and commands // set the flags and commands
app.Commands = c.Subcommands app.Commands = c.Subcommands
@@ -243,6 +266,7 @@ func (c Command) startApp(ctx *Context) error {
app.Author = ctx.App.Author app.Author = ctx.App.Author
app.Email = ctx.App.Email app.Email = ctx.App.Email
app.Writer = ctx.App.Writer app.Writer = ctx.App.Writer
app.ErrWriter = ctx.App.ErrWriter
app.categories = CommandCategories{} app.categories = CommandCategories{}
for _, command := range c.Subcommands { for _, command := range c.Subcommands {
@@ -265,6 +289,7 @@ func (c Command) startApp(ctx *Context) error {
} else { } else {
app.Action = helpSubcommand.Action app.Action = helpSubcommand.Action
} }
app.OnUsageError = c.OnUsageError
for index, cc := range app.Commands { for index, cc := range app.Commands {
app.Commands[index].commandNamePath = []string{c.Name, cc.Name} app.Commands[index].commandNamePath = []string{c.Name, cc.Name}

View File

@@ -3,9 +3,9 @@ package cli
import ( import (
"errors" "errors"
"flag" "flag"
"strconv" "reflect"
"strings" "strings"
"time" "syscall"
) )
// Context is a type that is passed through to // Context is a type that is passed through to
@@ -15,145 +15,21 @@ import (
type Context struct { type Context struct {
App *App App *App
Command Command Command Command
shellComplete bool
flagSet *flag.FlagSet flagSet *flag.FlagSet
setFlags map[string]bool setFlags map[string]bool
globalSetFlags map[string]bool
parentContext *Context parentContext *Context
} }
// NewContext creates a new context. For use in when invoking an App or Command action. // NewContext creates a new context. For use in when invoking an App or Command action.
func NewContext(app *App, set *flag.FlagSet, parentCtx *Context) *Context { func NewContext(app *App, set *flag.FlagSet, parentCtx *Context) *Context {
return &Context{App: app, flagSet: set, parentContext: parentCtx} c := &Context{App: app, flagSet: set, parentContext: parentCtx}
if parentCtx != nil {
c.shellComplete = parentCtx.shellComplete
} }
// Int looks up the value of a local int flag, returns 0 if no int flag exists return c
func (c *Context) Int(name string) int {
return lookupInt(name, c.flagSet)
}
// Duration looks up the value of a local time.Duration flag, returns 0 if no
// time.Duration flag exists
func (c *Context) Duration(name string) time.Duration {
return lookupDuration(name, c.flagSet)
}
// Float64 looks up the value of a local float64 flag, returns 0 if no float64
// flag exists
func (c *Context) Float64(name string) float64 {
return lookupFloat64(name, c.flagSet)
}
// Bool looks up the value of a local bool flag, returns false if no bool flag exists
func (c *Context) Bool(name string) bool {
return lookupBool(name, c.flagSet)
}
// BoolT looks up the value of a local boolT flag, returns false if no bool flag exists
func (c *Context) BoolT(name string) bool {
return lookupBoolT(name, c.flagSet)
}
// String looks up the value of a local string flag, returns "" if no string flag exists
func (c *Context) String(name string) string {
return lookupString(name, c.flagSet)
}
// StringSlice looks up the value of a local string slice flag, returns nil if no
// string slice flag exists
func (c *Context) StringSlice(name string) []string {
return lookupStringSlice(name, c.flagSet)
}
// IntSlice looks up the value of a local int slice flag, returns nil if no int
// slice flag exists
func (c *Context) IntSlice(name string) []int {
return lookupIntSlice(name, c.flagSet)
}
// Generic looks up the value of a local generic flag, returns nil if no generic
// flag exists
func (c *Context) Generic(name string) interface{} {
return lookupGeneric(name, c.flagSet)
}
// GlobalInt looks up the value of a global int flag, returns 0 if no int flag exists
func (c *Context) GlobalInt(name string) int {
if fs := lookupGlobalFlagSet(name, c); fs != nil {
return lookupInt(name, fs)
}
return 0
}
// GlobalFloat64 looks up the value of a global float64 flag, returns float64(0)
// if no float64 flag exists
func (c *Context) GlobalFloat64(name string) float64 {
if fs := lookupGlobalFlagSet(name, c); fs != nil {
return lookupFloat64(name, fs)
}
return float64(0)
}
// GlobalDuration looks up the value of a global time.Duration flag, returns 0
// if no time.Duration flag exists
func (c *Context) GlobalDuration(name string) time.Duration {
if fs := lookupGlobalFlagSet(name, c); fs != nil {
return lookupDuration(name, fs)
}
return 0
}
// GlobalBool looks up the value of a global bool flag, returns false if no bool
// flag exists
func (c *Context) GlobalBool(name string) bool {
if fs := lookupGlobalFlagSet(name, c); fs != nil {
return lookupBool(name, fs)
}
return false
}
// GlobalBoolT looks up the value of a global bool flag, returns true if no bool
// flag exists
func (c *Context) GlobalBoolT(name string) bool {
if fs := lookupGlobalFlagSet(name, c); fs != nil {
return lookupBoolT(name, fs)
}
return false
}
// GlobalString looks up the value of a global string flag, returns "" if no
// string flag exists
func (c *Context) GlobalString(name string) string {
if fs := lookupGlobalFlagSet(name, c); fs != nil {
return lookupString(name, fs)
}
return ""
}
// GlobalStringSlice looks up the value of a global string slice flag, returns
// nil if no string slice flag exists
func (c *Context) GlobalStringSlice(name string) []string {
if fs := lookupGlobalFlagSet(name, c); fs != nil {
return lookupStringSlice(name, fs)
}
return nil
}
// GlobalIntSlice looks up the value of a global int slice flag, returns nil if
// no int slice flag exists
func (c *Context) GlobalIntSlice(name string) []int {
if fs := lookupGlobalFlagSet(name, c); fs != nil {
return lookupIntSlice(name, fs)
}
return nil
}
// GlobalGeneric looks up the value of a global generic flag, returns nil if no
// generic flag exists
func (c *Context) GlobalGeneric(name string) interface{} {
if fs := lookupGlobalFlagSet(name, c); fs != nil {
return lookupGeneric(name, fs)
}
return nil
} }
// NumFlags returns the number of flags set // NumFlags returns the number of flags set
@@ -163,11 +39,13 @@ func (c *Context) NumFlags() int {
// Set sets a context flag to a value. // Set sets a context flag to a value.
func (c *Context) Set(name, value string) error { func (c *Context) Set(name, value string) error {
c.setFlags = nil
return c.flagSet.Set(name, value) return c.flagSet.Set(name, value)
} }
// GlobalSet sets a context flag to a value on the global flagset // GlobalSet sets a context flag to a value on the global flagset
func (c *Context) GlobalSet(name, value string) error { func (c *Context) GlobalSet(name, value string) error {
globalContext(c).setFlags = nil
return globalContext(c).flagSet.Set(name, value) return globalContext(c).flagSet.Set(name, value)
} }
@@ -175,28 +53,78 @@ func (c *Context) GlobalSet(name, value string) error {
func (c *Context) IsSet(name string) bool { func (c *Context) IsSet(name string) bool {
if c.setFlags == nil { if c.setFlags == nil {
c.setFlags = make(map[string]bool) c.setFlags = make(map[string]bool)
c.flagSet.Visit(func(f *flag.Flag) { c.flagSet.Visit(func(f *flag.Flag) {
c.setFlags[f.Name] = true c.setFlags[f.Name] = true
}) })
c.flagSet.VisitAll(func(f *flag.Flag) {
if _, ok := c.setFlags[f.Name]; ok {
return
} }
return c.setFlags[name] == true c.setFlags[f.Name] = false
})
// XXX hack to support IsSet for flags with EnvVar
//
// There isn't an easy way to do this with the current implementation since
// whether a flag was set via an environment variable is very difficult to
// determine here. Instead, we intend to introduce a backwards incompatible
// change in version 2 to add `IsSet` to the Flag interface to push the
// responsibility closer to where the information required to determine
// whether a flag is set by non-standard means such as environment
// variables is avaliable.
//
// See https://github.com/urfave/cli/issues/294 for additional discussion
flags := c.Command.Flags
if c.Command.Name == "" { // cannot == Command{} since it contains slice types
if c.App != nil {
flags = c.App.Flags
}
}
for _, f := range flags {
eachName(f.GetName(), func(name string) {
if isSet, ok := c.setFlags[name]; isSet || !ok {
return
}
val := reflect.ValueOf(f)
if val.Kind() == reflect.Ptr {
val = val.Elem()
}
envVarValue := val.FieldByName("EnvVar")
if !envVarValue.IsValid() {
return
}
eachName(envVarValue.String(), func(envVar string) {
envVar = strings.TrimSpace(envVar)
if _, ok := syscall.Getenv(envVar); ok {
c.setFlags[name] = true
return
}
})
})
}
}
return c.setFlags[name]
} }
// GlobalIsSet determines if the global flag was actually set // GlobalIsSet determines if the global flag was actually set
func (c *Context) GlobalIsSet(name string) bool { func (c *Context) GlobalIsSet(name string) bool {
if c.globalSetFlags == nil {
c.globalSetFlags = make(map[string]bool)
ctx := c ctx := c
if ctx.parentContext != nil { if ctx.parentContext != nil {
ctx = ctx.parentContext ctx = ctx.parentContext
} }
for ; ctx != nil && c.globalSetFlags[name] == false; ctx = ctx.parentContext {
ctx.flagSet.Visit(func(f *flag.Flag) { for ; ctx != nil; ctx = ctx.parentContext {
c.globalSetFlags[f.Name] = true if ctx.IsSet(name) {
}) return true
} }
} }
return c.globalSetFlags[name] return false
} }
// FlagNames returns a slice of flag names used in this context. // FlagNames returns a slice of flag names used in this context.
@@ -228,6 +156,11 @@ func (c *Context) Parent() *Context {
return c.parentContext return c.parentContext
} }
// value returns the value of the flag coressponding to `name`
func (c *Context) value(name string) interface{} {
return c.flagSet.Lookup(name).Value.(flag.Getter).Get()
}
// Args contains apps console arguments // Args contains apps console arguments
type Args []string type Args []string
@@ -303,107 +236,6 @@ func lookupGlobalFlagSet(name string, ctx *Context) *flag.FlagSet {
return nil return nil
} }
func lookupInt(name string, set *flag.FlagSet) int {
f := set.Lookup(name)
if f != nil {
val, err := strconv.Atoi(f.Value.String())
if err != nil {
return 0
}
return val
}
return 0
}
func lookupDuration(name string, set *flag.FlagSet) time.Duration {
f := set.Lookup(name)
if f != nil {
val, err := time.ParseDuration(f.Value.String())
if err == nil {
return val
}
}
return 0
}
func lookupFloat64(name string, set *flag.FlagSet) float64 {
f := set.Lookup(name)
if f != nil {
val, err := strconv.ParseFloat(f.Value.String(), 64)
if err != nil {
return 0
}
return val
}
return 0
}
func lookupString(name string, set *flag.FlagSet) string {
f := set.Lookup(name)
if f != nil {
return f.Value.String()
}
return ""
}
func lookupStringSlice(name string, set *flag.FlagSet) []string {
f := set.Lookup(name)
if f != nil {
return (f.Value.(*StringSlice)).Value()
}
return nil
}
func lookupIntSlice(name string, set *flag.FlagSet) []int {
f := set.Lookup(name)
if f != nil {
return (f.Value.(*IntSlice)).Value()
}
return nil
}
func lookupGeneric(name string, set *flag.FlagSet) interface{} {
f := set.Lookup(name)
if f != nil {
return f.Value
}
return nil
}
func lookupBool(name string, set *flag.FlagSet) bool {
f := set.Lookup(name)
if f != nil {
val, err := strconv.ParseBool(f.Value.String())
if err != nil {
return false
}
return val
}
return false
}
func lookupBoolT(name string, set *flag.FlagSet) bool {
f := set.Lookup(name)
if f != nil {
val, err := strconv.ParseBool(f.Value.String())
if err != nil {
return true
}
return val
}
return false
}
func copyFlag(name string, ff *flag.Flag, set *flag.FlagSet) { func copyFlag(name string, ff *flag.Flag, set *flag.FlagSet) {
switch ff.Value.(type) { switch ff.Value.(type) {
case *StringSlice: case *StringSlice:

View File

@@ -24,7 +24,7 @@ func NewMultiError(err ...error) MultiError {
return MultiError{Errors: err} return MultiError{Errors: err}
} }
// Error implents the error interface. // Error implements the error interface.
func (m MultiError) Error() string { func (m MultiError) Error() string {
errs := make([]string, len(m.Errors)) errs := make([]string, len(m.Errors))
for i, err := range m.Errors { for i, err := range m.Errors {
@@ -34,6 +34,10 @@ func (m MultiError) Error() string {
return strings.Join(errs, "\n") return strings.Join(errs, "\n")
} }
type ErrorFormatter interface {
Format(s fmt.State, verb rune)
}
// ExitCoder is the interface checked by `App` and `Command` for a custom exit // ExitCoder is the interface checked by `App` and `Command` for a custom exit
// code // code
type ExitCoder interface { type ExitCoder interface {
@@ -44,11 +48,11 @@ type ExitCoder interface {
// ExitError fulfills both the builtin `error` interface and `ExitCoder` // ExitError fulfills both the builtin `error` interface and `ExitCoder`
type ExitError struct { type ExitError struct {
exitCode int exitCode int
message string message interface{}
} }
// NewExitError makes a new *ExitError // NewExitError makes a new *ExitError
func NewExitError(message string, exitCode int) *ExitError { func NewExitError(message interface{}, exitCode int) *ExitError {
return &ExitError{ return &ExitError{
exitCode: exitCode, exitCode: exitCode,
message: message, message: message,
@@ -58,7 +62,7 @@ func NewExitError(message string, exitCode int) *ExitError {
// Error returns the string message, fulfilling the interface required by // Error returns the string message, fulfilling the interface required by
// `error` // `error`
func (ee *ExitError) Error() string { func (ee *ExitError) Error() string {
return ee.message return fmt.Sprintf("%v", ee.message)
} }
// ExitCode returns the exit code, fulfilling the interface required by // ExitCode returns the exit code, fulfilling the interface required by
@@ -70,7 +74,7 @@ func (ee *ExitError) ExitCode() int {
// HandleExitCoder checks if the error fulfills the ExitCoder interface, and if // HandleExitCoder checks if the error fulfills the ExitCoder interface, and if
// so prints the error to stderr (if it is non-empty) and calls OsExiter with the // so prints the error to stderr (if it is non-empty) and calls OsExiter with the
// given exit code. If the given error is a MultiError, then this func is // given exit code. If the given error is a MultiError, then this func is
// called on all members of the Errors slice. // called on all members of the Errors slice and calls OsExiter with the last exit code.
func HandleExitCoder(err error) { func HandleExitCoder(err error) {
if err == nil { if err == nil {
return return
@@ -78,15 +82,34 @@ func HandleExitCoder(err error) {
if exitErr, ok := err.(ExitCoder); ok { if exitErr, ok := err.(ExitCoder); ok {
if err.Error() != "" { if err.Error() != "" {
if _, ok := exitErr.(ErrorFormatter); ok {
fmt.Fprintf(ErrWriter, "%+v\n", err)
} else {
fmt.Fprintln(ErrWriter, err) fmt.Fprintln(ErrWriter, err)
} }
}
OsExiter(exitErr.ExitCode()) OsExiter(exitErr.ExitCode())
return return
} }
if multiErr, ok := err.(MultiError); ok { if multiErr, ok := err.(MultiError); ok {
code := handleMultiError(multiErr)
OsExiter(code)
return
}
}
func handleMultiError(multiErr MultiError) int {
code := 1
for _, merr := range multiErr.Errors { for _, merr := range multiErr.Errors {
HandleExitCoder(merr) if multiErr2, ok := merr.(MultiError); ok {
code = handleMultiError(multiErr2)
} else {
fmt.Fprintln(ErrWriter, merr)
if exitErr, ok := merr.(ExitCoder); ok {
code = exitErr.ExitCode()
} }
} }
} }
return code
}

556
vendor/github.com/urfave/cli/flag.go generated vendored
View File

@@ -3,24 +3,24 @@ package cli
import ( import (
"flag" "flag"
"fmt" "fmt"
"os"
"reflect" "reflect"
"runtime" "runtime"
"strconv" "strconv"
"strings" "strings"
"syscall"
"time" "time"
) )
const defaultPlaceholder = "value" const defaultPlaceholder = "value"
// BashCompletionFlag enables bash-completion for all commands and subcommands // BashCompletionFlag enables bash-completion for all commands and subcommands
var BashCompletionFlag = BoolFlag{ var BashCompletionFlag Flag = BoolFlag{
Name: "generate-bash-completion", Name: "generate-bash-completion",
Hidden: true, Hidden: true,
} }
// VersionFlag prints the version for the application // VersionFlag prints the version for the application
var VersionFlag = BoolFlag{ var VersionFlag Flag = BoolFlag{
Name: "version, v", Name: "version, v",
Usage: "print the version", Usage: "print the version",
} }
@@ -28,7 +28,7 @@ var VersionFlag = BoolFlag{
// HelpFlag prints the help for all commands and subcommands // HelpFlag prints the help for all commands and subcommands
// Set to the zero value (BoolFlag{}) to disable flag -- keeps subcommand // Set to the zero value (BoolFlag{}) to disable flag -- keeps subcommand
// unless HideHelp is set to true) // unless HideHelp is set to true)
var HelpFlag = BoolFlag{ var HelpFlag Flag = BoolFlag{
Name: "help, h", Name: "help, h",
Usage: "show help", Usage: "show help",
} }
@@ -37,6 +37,21 @@ var HelpFlag = BoolFlag{
// to display a flag. // to display a flag.
var FlagStringer FlagStringFunc = stringifyFlag var FlagStringer FlagStringFunc = stringifyFlag
// FlagsByName is a slice of Flag.
type FlagsByName []Flag
func (f FlagsByName) Len() int {
return len(f)
}
func (f FlagsByName) Less(i, j int) bool {
return f[i].GetName() < f[j].GetName()
}
func (f FlagsByName) Swap(i, j int) {
f[i], f[j] = f[j], f[i]
}
// Flag is a common interface related to parsing flags in cli. // Flag is a common interface related to parsing flags in cli.
// For more advanced flag parsing techniques, it is recommended that // For more advanced flag parsing techniques, it is recommended that
// this interface be implemented. // this interface be implemented.
@@ -47,13 +62,29 @@ type Flag interface {
GetName() string GetName() string
} }
func flagSet(name string, flags []Flag) *flag.FlagSet { // errorableFlag is an interface that allows us to return errors during apply
// it allows flags defined in this library to return errors in a fashion backwards compatible
// TODO remove in v2 and modify the existing Flag interface to return errors
type errorableFlag interface {
Flag
ApplyWithError(*flag.FlagSet) error
}
func flagSet(name string, flags []Flag) (*flag.FlagSet, error) {
set := flag.NewFlagSet(name, flag.ContinueOnError) set := flag.NewFlagSet(name, flag.ContinueOnError)
for _, f := range flags { for _, f := range flags {
//TODO remove in v2 when errorableFlag is removed
if ef, ok := f.(errorableFlag); ok {
if err := ef.ApplyWithError(set); err != nil {
return nil, err
}
} else {
f.Apply(set) f.Apply(set)
} }
return set }
return set, nil
} }
func eachName(longName string, fn func(string)) { func eachName(longName string, fn func(string)) {
@@ -70,31 +101,24 @@ type Generic interface {
String() string String() string
} }
// GenericFlag is the flag type for types implementing Generic
type GenericFlag struct {
Name string
Value Generic
Usage string
EnvVar string
Hidden bool
}
// String returns the string representation of the generic flag to display the
// help text to the user (uses the String() method of the generic flag to show
// the value)
func (f GenericFlag) String() string {
return FlagStringer(f)
}
// Apply takes the flagset and calls Set on the generic flag with the value // Apply takes the flagset and calls Set on the generic flag with the value
// provided by the user for parsing by the flag // provided by the user for parsing by the flag
// Ignores parsing errors
func (f GenericFlag) Apply(set *flag.FlagSet) { func (f GenericFlag) Apply(set *flag.FlagSet) {
f.ApplyWithError(set)
}
// ApplyWithError takes the flagset and calls Set on the generic flag with the value
// provided by the user for parsing by the flag
func (f GenericFlag) ApplyWithError(set *flag.FlagSet) error {
val := f.Value val := f.Value
if f.EnvVar != "" { if f.EnvVar != "" {
for _, envVar := range strings.Split(f.EnvVar, ",") { for _, envVar := range strings.Split(f.EnvVar, ",") {
envVar = strings.TrimSpace(envVar) envVar = strings.TrimSpace(envVar)
if envVal := os.Getenv(envVar); envVal != "" { if envVal, ok := syscall.Getenv(envVar); ok {
val.Set(envVal) if err := val.Set(envVal); err != nil {
return fmt.Errorf("could not parse %s as value for flag %s: %s", envVal, f.Name, err)
}
break break
} }
} }
@@ -103,14 +127,11 @@ func (f GenericFlag) Apply(set *flag.FlagSet) {
eachName(f.Name, func(name string) { eachName(f.Name, func(name string) {
set.Var(f.Value, name, f.Usage) set.Var(f.Value, name, f.Usage)
}) })
return nil
} }
// GetName returns the name of a flag. // StringSlice is an opaque type for []string to satisfy flag.Value and flag.Getter
func (f GenericFlag) GetName() string {
return f.Name
}
// StringSlice is an opaque type for []string to satisfy flag.Value
type StringSlice []string type StringSlice []string
// Set appends the string value to the list of values // Set appends the string value to the list of values
@@ -129,31 +150,29 @@ func (f *StringSlice) Value() []string {
return *f return *f
} }
// StringSliceFlag is a string flag that can be specified multiple times on the // Get returns the slice of strings set by this flag
// command-line func (f *StringSlice) Get() interface{} {
type StringSliceFlag struct { return *f
Name string
Value *StringSlice
Usage string
EnvVar string
Hidden bool
}
// String returns the usage
func (f StringSliceFlag) String() string {
return FlagStringer(f)
} }
// Apply populates the flag given the flag set and environment // Apply populates the flag given the flag set and environment
// Ignores errors
func (f StringSliceFlag) Apply(set *flag.FlagSet) { func (f StringSliceFlag) Apply(set *flag.FlagSet) {
f.ApplyWithError(set)
}
// ApplyWithError populates the flag given the flag set and environment
func (f StringSliceFlag) ApplyWithError(set *flag.FlagSet) error {
if f.EnvVar != "" { if f.EnvVar != "" {
for _, envVar := range strings.Split(f.EnvVar, ",") { for _, envVar := range strings.Split(f.EnvVar, ",") {
envVar = strings.TrimSpace(envVar) envVar = strings.TrimSpace(envVar)
if envVal := os.Getenv(envVar); envVal != "" { if envVal, ok := syscall.Getenv(envVar); ok {
newVal := &StringSlice{} newVal := &StringSlice{}
for _, s := range strings.Split(envVal, ",") { for _, s := range strings.Split(envVal, ",") {
s = strings.TrimSpace(s) s = strings.TrimSpace(s)
newVal.Set(s) if err := newVal.Set(s); err != nil {
return fmt.Errorf("could not parse %s as string value for flag %s: %s", envVal, f.Name, err)
}
} }
f.Value = newVal f.Value = newVal
break break
@@ -167,14 +186,11 @@ func (f StringSliceFlag) Apply(set *flag.FlagSet) {
} }
set.Var(f.Value, name, f.Usage) set.Var(f.Value, name, f.Usage)
}) })
return nil
} }
// GetName returns the name of a flag. // IntSlice is an opaque type for []int to satisfy flag.Value and flag.Getter
func (f StringSliceFlag) GetName() string {
return f.Name
}
// IntSlice is an opaque type for []int to satisfy flag.Value
type IntSlice []int type IntSlice []int
// Set parses the value into an integer and appends it to the list of values // Set parses the value into an integer and appends it to the list of values
@@ -189,7 +205,7 @@ func (f *IntSlice) Set(value string) error {
// String returns a readable representation of this value (for usage defaults) // String returns a readable representation of this value (for usage defaults)
func (f *IntSlice) String() string { func (f *IntSlice) String() string {
return fmt.Sprintf("%d", *f) return fmt.Sprintf("%#v", *f)
} }
// Value returns the slice of ints set by this flag // Value returns the slice of ints set by this flag
@@ -197,33 +213,28 @@ func (f *IntSlice) Value() []int {
return *f return *f
} }
// IntSliceFlag is an int flag that can be specified multiple times on the // Get returns the slice of ints set by this flag
// command-line func (f *IntSlice) Get() interface{} {
type IntSliceFlag struct { return *f
Name string
Value *IntSlice
Usage string
EnvVar string
Hidden bool
}
// String returns the usage
func (f IntSliceFlag) String() string {
return FlagStringer(f)
} }
// Apply populates the flag given the flag set and environment // Apply populates the flag given the flag set and environment
// Ignores errors
func (f IntSliceFlag) Apply(set *flag.FlagSet) { func (f IntSliceFlag) Apply(set *flag.FlagSet) {
f.ApplyWithError(set)
}
// ApplyWithError populates the flag given the flag set and environment
func (f IntSliceFlag) ApplyWithError(set *flag.FlagSet) error {
if f.EnvVar != "" { if f.EnvVar != "" {
for _, envVar := range strings.Split(f.EnvVar, ",") { for _, envVar := range strings.Split(f.EnvVar, ",") {
envVar = strings.TrimSpace(envVar) envVar = strings.TrimSpace(envVar)
if envVal := os.Getenv(envVar); envVal != "" { if envVal, ok := syscall.Getenv(envVar); ok {
newVal := &IntSlice{} newVal := &IntSlice{}
for _, s := range strings.Split(envVal, ",") { for _, s := range strings.Split(envVal, ",") {
s = strings.TrimSpace(s) s = strings.TrimSpace(s)
err := newVal.Set(s) if err := newVal.Set(s); err != nil {
if err != nil { return fmt.Errorf("could not parse %s as int slice value for flag %s: %s", envVal, f.Name, err)
fmt.Fprintf(ErrWriter, err.Error())
} }
} }
f.Value = newVal f.Value = newVal
@@ -238,38 +249,96 @@ func (f IntSliceFlag) Apply(set *flag.FlagSet) {
} }
set.Var(f.Value, name, f.Usage) set.Var(f.Value, name, f.Usage)
}) })
return nil
} }
// GetName returns the name of the flag. // Int64Slice is an opaque type for []int to satisfy flag.Value and flag.Getter
func (f IntSliceFlag) GetName() string { type Int64Slice []int64
return f.Name
}
// BoolFlag is a switch that defaults to false // Set parses the value into an integer and appends it to the list of values
type BoolFlag struct { func (f *Int64Slice) Set(value string) error {
Name string tmp, err := strconv.ParseInt(value, 10, 64)
Usage string if err != nil {
EnvVar string return err
Destination *bool }
Hidden bool *f = append(*f, tmp)
return nil
} }
// String returns a readable representation of this value (for usage defaults) // String returns a readable representation of this value (for usage defaults)
func (f BoolFlag) String() string { func (f *Int64Slice) String() string {
return FlagStringer(f) return fmt.Sprintf("%#v", *f)
}
// Value returns the slice of ints set by this flag
func (f *Int64Slice) Value() []int64 {
return *f
}
// Get returns the slice of ints set by this flag
func (f *Int64Slice) Get() interface{} {
return *f
} }
// Apply populates the flag given the flag set and environment // Apply populates the flag given the flag set and environment
// Ignores errors
func (f Int64SliceFlag) Apply(set *flag.FlagSet) {
f.ApplyWithError(set)
}
// ApplyWithError populates the flag given the flag set and environment
func (f Int64SliceFlag) ApplyWithError(set *flag.FlagSet) error {
if f.EnvVar != "" {
for _, envVar := range strings.Split(f.EnvVar, ",") {
envVar = strings.TrimSpace(envVar)
if envVal, ok := syscall.Getenv(envVar); ok {
newVal := &Int64Slice{}
for _, s := range strings.Split(envVal, ",") {
s = strings.TrimSpace(s)
if err := newVal.Set(s); err != nil {
return fmt.Errorf("could not parse %s as int64 slice value for flag %s: %s", envVal, f.Name, err)
}
}
f.Value = newVal
break
}
}
}
eachName(f.Name, func(name string) {
if f.Value == nil {
f.Value = &Int64Slice{}
}
set.Var(f.Value, name, f.Usage)
})
return nil
}
// Apply populates the flag given the flag set and environment
// Ignores errors
func (f BoolFlag) Apply(set *flag.FlagSet) { func (f BoolFlag) Apply(set *flag.FlagSet) {
f.ApplyWithError(set)
}
// ApplyWithError populates the flag given the flag set and environment
func (f BoolFlag) ApplyWithError(set *flag.FlagSet) error {
val := false val := false
if f.EnvVar != "" { if f.EnvVar != "" {
for _, envVar := range strings.Split(f.EnvVar, ",") { for _, envVar := range strings.Split(f.EnvVar, ",") {
envVar = strings.TrimSpace(envVar) envVar = strings.TrimSpace(envVar)
if envVal := os.Getenv(envVar); envVal != "" { if envVal, ok := syscall.Getenv(envVar); ok {
envValBool, err := strconv.ParseBool(envVal) if envVal == "" {
if err == nil { val = false
val = envValBool break
} }
envValBool, err := strconv.ParseBool(envVal)
if err != nil {
return fmt.Errorf("could not parse %s as bool value for flag %s: %s", envVal, f.Name, err)
}
val = envValBool
break break
} }
} }
@@ -282,40 +351,35 @@ func (f BoolFlag) Apply(set *flag.FlagSet) {
} }
set.Bool(name, val, f.Usage) set.Bool(name, val, f.Usage)
}) })
}
// GetName returns the name of the flag. return nil
func (f BoolFlag) GetName() string {
return f.Name
}
// BoolTFlag this represents a boolean flag that is true by default, but can
// still be set to false by --some-flag=false
type BoolTFlag struct {
Name string
Usage string
EnvVar string
Destination *bool
Hidden bool
}
// String returns a readable representation of this value (for usage defaults)
func (f BoolTFlag) String() string {
return FlagStringer(f)
} }
// Apply populates the flag given the flag set and environment // Apply populates the flag given the flag set and environment
// Ignores errors
func (f BoolTFlag) Apply(set *flag.FlagSet) { func (f BoolTFlag) Apply(set *flag.FlagSet) {
f.ApplyWithError(set)
}
// ApplyWithError populates the flag given the flag set and environment
func (f BoolTFlag) ApplyWithError(set *flag.FlagSet) error {
val := true val := true
if f.EnvVar != "" { if f.EnvVar != "" {
for _, envVar := range strings.Split(f.EnvVar, ",") { for _, envVar := range strings.Split(f.EnvVar, ",") {
envVar = strings.TrimSpace(envVar) envVar = strings.TrimSpace(envVar)
if envVal := os.Getenv(envVar); envVal != "" { if envVal, ok := syscall.Getenv(envVar); ok {
envValBool, err := strconv.ParseBool(envVal) if envVal == "" {
if err == nil { val = false
val = envValBool
break break
} }
envValBool, err := strconv.ParseBool(envVal)
if err != nil {
return fmt.Errorf("could not parse %s as bool value for flag %s: %s", envVal, f.Name, err)
}
val = envValBool
break
} }
} }
} }
@@ -327,34 +391,22 @@ func (f BoolTFlag) Apply(set *flag.FlagSet) {
} }
set.Bool(name, val, f.Usage) set.Bool(name, val, f.Usage)
}) })
}
// GetName returns the name of the flag. return nil
func (f BoolTFlag) GetName() string {
return f.Name
}
// StringFlag represents a flag that takes as string value
type StringFlag struct {
Name string
Value string
Usage string
EnvVar string
Destination *string
Hidden bool
}
// String returns the usage
func (f StringFlag) String() string {
return FlagStringer(f)
} }
// Apply populates the flag given the flag set and environment // Apply populates the flag given the flag set and environment
// Ignores errors
func (f StringFlag) Apply(set *flag.FlagSet) { func (f StringFlag) Apply(set *flag.FlagSet) {
f.ApplyWithError(set)
}
// ApplyWithError populates the flag given the flag set and environment
func (f StringFlag) ApplyWithError(set *flag.FlagSet) error {
if f.EnvVar != "" { if f.EnvVar != "" {
for _, envVar := range strings.Split(f.EnvVar, ",") { for _, envVar := range strings.Split(f.EnvVar, ",") {
envVar = strings.TrimSpace(envVar) envVar = strings.TrimSpace(envVar)
if envVal := os.Getenv(envVar); envVal != "" { if envVal, ok := syscall.Getenv(envVar); ok {
f.Value = envVal f.Value = envVal
break break
} }
@@ -368,43 +420,31 @@ func (f StringFlag) Apply(set *flag.FlagSet) {
} }
set.String(name, f.Value, f.Usage) set.String(name, f.Value, f.Usage)
}) })
}
// GetName returns the name of the flag. return nil
func (f StringFlag) GetName() string {
return f.Name
}
// IntFlag is a flag that takes an integer
// Errors if the value provided cannot be parsed
type IntFlag struct {
Name string
Value int
Usage string
EnvVar string
Destination *int
Hidden bool
}
// String returns the usage
func (f IntFlag) String() string {
return FlagStringer(f)
} }
// Apply populates the flag given the flag set and environment // Apply populates the flag given the flag set and environment
// Ignores errors
func (f IntFlag) Apply(set *flag.FlagSet) { func (f IntFlag) Apply(set *flag.FlagSet) {
f.ApplyWithError(set)
}
// ApplyWithError populates the flag given the flag set and environment
func (f IntFlag) ApplyWithError(set *flag.FlagSet) error {
if f.EnvVar != "" { if f.EnvVar != "" {
for _, envVar := range strings.Split(f.EnvVar, ",") { for _, envVar := range strings.Split(f.EnvVar, ",") {
envVar = strings.TrimSpace(envVar) envVar = strings.TrimSpace(envVar)
if envVal := os.Getenv(envVar); envVal != "" { if envVal, ok := syscall.Getenv(envVar); ok {
envValInt, err := strconv.ParseInt(envVal, 0, 64) envValInt, err := strconv.ParseInt(envVal, 0, 64)
if err == nil { if err != nil {
return fmt.Errorf("could not parse %s as int value for flag %s: %s", envVal, f.Name, err)
}
f.Value = int(envValInt) f.Value = int(envValInt)
break break
} }
} }
} }
}
eachName(f.Name, func(name string) { eachName(f.Name, func(name string) {
if f.Destination != nil { if f.Destination != nil {
@@ -413,42 +453,133 @@ func (f IntFlag) Apply(set *flag.FlagSet) {
} }
set.Int(name, f.Value, f.Usage) set.Int(name, f.Value, f.Usage)
}) })
}
// GetName returns the name of the flag. return nil
func (f IntFlag) GetName() string {
return f.Name
}
// DurationFlag is a flag that takes a duration specified in Go's duration
// format: https://golang.org/pkg/time/#ParseDuration
type DurationFlag struct {
Name string
Value time.Duration
Usage string
EnvVar string
Destination *time.Duration
Hidden bool
}
// String returns a readable representation of this value (for usage defaults)
func (f DurationFlag) String() string {
return FlagStringer(f)
} }
// Apply populates the flag given the flag set and environment // Apply populates the flag given the flag set and environment
func (f DurationFlag) Apply(set *flag.FlagSet) { // Ignores errors
func (f Int64Flag) Apply(set *flag.FlagSet) {
f.ApplyWithError(set)
}
// ApplyWithError populates the flag given the flag set and environment
func (f Int64Flag) ApplyWithError(set *flag.FlagSet) error {
if f.EnvVar != "" { if f.EnvVar != "" {
for _, envVar := range strings.Split(f.EnvVar, ",") { for _, envVar := range strings.Split(f.EnvVar, ",") {
envVar = strings.TrimSpace(envVar) envVar = strings.TrimSpace(envVar)
if envVal := os.Getenv(envVar); envVal != "" { if envVal, ok := syscall.Getenv(envVar); ok {
envValDuration, err := time.ParseDuration(envVal) envValInt, err := strconv.ParseInt(envVal, 0, 64)
if err == nil { if err != nil {
f.Value = envValDuration return fmt.Errorf("could not parse %s as int value for flag %s: %s", envVal, f.Name, err)
}
f.Value = envValInt
break break
} }
} }
} }
eachName(f.Name, func(name string) {
if f.Destination != nil {
set.Int64Var(f.Destination, name, f.Value, f.Usage)
return
}
set.Int64(name, f.Value, f.Usage)
})
return nil
}
// Apply populates the flag given the flag set and environment
// Ignores errors
func (f UintFlag) Apply(set *flag.FlagSet) {
f.ApplyWithError(set)
}
// ApplyWithError populates the flag given the flag set and environment
func (f UintFlag) ApplyWithError(set *flag.FlagSet) error {
if f.EnvVar != "" {
for _, envVar := range strings.Split(f.EnvVar, ",") {
envVar = strings.TrimSpace(envVar)
if envVal, ok := syscall.Getenv(envVar); ok {
envValInt, err := strconv.ParseUint(envVal, 0, 64)
if err != nil {
return fmt.Errorf("could not parse %s as uint value for flag %s: %s", envVal, f.Name, err)
}
f.Value = uint(envValInt)
break
}
}
}
eachName(f.Name, func(name string) {
if f.Destination != nil {
set.UintVar(f.Destination, name, f.Value, f.Usage)
return
}
set.Uint(name, f.Value, f.Usage)
})
return nil
}
// Apply populates the flag given the flag set and environment
// Ignores errors
func (f Uint64Flag) Apply(set *flag.FlagSet) {
f.ApplyWithError(set)
}
// ApplyWithError populates the flag given the flag set and environment
func (f Uint64Flag) ApplyWithError(set *flag.FlagSet) error {
if f.EnvVar != "" {
for _, envVar := range strings.Split(f.EnvVar, ",") {
envVar = strings.TrimSpace(envVar)
if envVal, ok := syscall.Getenv(envVar); ok {
envValInt, err := strconv.ParseUint(envVal, 0, 64)
if err != nil {
return fmt.Errorf("could not parse %s as uint64 value for flag %s: %s", envVal, f.Name, err)
}
f.Value = uint64(envValInt)
break
}
}
}
eachName(f.Name, func(name string) {
if f.Destination != nil {
set.Uint64Var(f.Destination, name, f.Value, f.Usage)
return
}
set.Uint64(name, f.Value, f.Usage)
})
return nil
}
// Apply populates the flag given the flag set and environment
// Ignores errors
func (f DurationFlag) Apply(set *flag.FlagSet) {
f.ApplyWithError(set)
}
// ApplyWithError populates the flag given the flag set and environment
func (f DurationFlag) ApplyWithError(set *flag.FlagSet) error {
if f.EnvVar != "" {
for _, envVar := range strings.Split(f.EnvVar, ",") {
envVar = strings.TrimSpace(envVar)
if envVal, ok := syscall.Getenv(envVar); ok {
envValDuration, err := time.ParseDuration(envVal)
if err != nil {
return fmt.Errorf("could not parse %s as duration for flag %s: %s", envVal, f.Name, err)
}
f.Value = envValDuration
break
}
}
} }
eachName(f.Name, func(name string) { eachName(f.Name, func(name string) {
@@ -458,39 +589,29 @@ func (f DurationFlag) Apply(set *flag.FlagSet) {
} }
set.Duration(name, f.Value, f.Usage) set.Duration(name, f.Value, f.Usage)
}) })
}
// GetName returns the name of the flag. return nil
func (f DurationFlag) GetName() string {
return f.Name
}
// Float64Flag is a flag that takes an float value
// Errors if the value provided cannot be parsed
type Float64Flag struct {
Name string
Value float64
Usage string
EnvVar string
Destination *float64
Hidden bool
}
// String returns the usage
func (f Float64Flag) String() string {
return FlagStringer(f)
} }
// Apply populates the flag given the flag set and environment // Apply populates the flag given the flag set and environment
// Ignores errors
func (f Float64Flag) Apply(set *flag.FlagSet) { func (f Float64Flag) Apply(set *flag.FlagSet) {
f.ApplyWithError(set)
}
// ApplyWithError populates the flag given the flag set and environment
func (f Float64Flag) ApplyWithError(set *flag.FlagSet) error {
if f.EnvVar != "" { if f.EnvVar != "" {
for _, envVar := range strings.Split(f.EnvVar, ",") { for _, envVar := range strings.Split(f.EnvVar, ",") {
envVar = strings.TrimSpace(envVar) envVar = strings.TrimSpace(envVar)
if envVal := os.Getenv(envVar); envVal != "" { if envVal, ok := syscall.Getenv(envVar); ok {
envValFloat, err := strconv.ParseFloat(envVal, 10) envValFloat, err := strconv.ParseFloat(envVal, 10)
if err == nil { if err != nil {
f.Value = float64(envValFloat) return fmt.Errorf("could not parse %s as float64 value for flag %s: %s", envVal, f.Name, err)
} }
f.Value = float64(envValFloat)
break
} }
} }
} }
@@ -502,17 +623,15 @@ func (f Float64Flag) Apply(set *flag.FlagSet) {
} }
set.Float64(name, f.Value, f.Usage) set.Float64(name, f.Value, f.Usage)
}) })
}
// GetName returns the name of the flag. return nil
func (f Float64Flag) GetName() string {
return f.Name
} }
func visibleFlags(fl []Flag) []Flag { func visibleFlags(fl []Flag) []Flag {
visible := []Flag{} visible := []Flag{}
for _, flag := range fl { for _, flag := range fl {
if !reflect.ValueOf(flag).FieldByName("Hidden").Bool() { field := flagValue(flag).FieldByName("Hidden")
if !field.IsValid() || !field.Bool() {
visible = append(visible, flag) visible = append(visible, flag)
} }
} }
@@ -578,13 +697,24 @@ func withEnvHint(envVar, str string) string {
return str + envText return str + envText
} }
func stringifyFlag(f Flag) string { func flagValue(f Flag) reflect.Value {
fv := reflect.ValueOf(f) fv := reflect.ValueOf(f)
for fv.Kind() == reflect.Ptr {
fv = reflect.Indirect(fv)
}
return fv
}
func stringifyFlag(f Flag) string {
fv := flagValue(f)
switch f.(type) { switch f.(type) {
case IntSliceFlag: case IntSliceFlag:
return withEnvHint(fv.FieldByName("EnvVar").String(), return withEnvHint(fv.FieldByName("EnvVar").String(),
stringifyIntSliceFlag(f.(IntSliceFlag))) stringifyIntSliceFlag(f.(IntSliceFlag)))
case Int64SliceFlag:
return withEnvHint(fv.FieldByName("EnvVar").String(),
stringifyInt64SliceFlag(f.(Int64SliceFlag)))
case StringSliceFlag: case StringSliceFlag:
return withEnvHint(fv.FieldByName("EnvVar").String(), return withEnvHint(fv.FieldByName("EnvVar").String(),
stringifyStringSliceFlag(f.(StringSliceFlag))) stringifyStringSliceFlag(f.(StringSliceFlag)))
@@ -594,9 +724,8 @@ func stringifyFlag(f Flag) string {
needsPlaceholder := false needsPlaceholder := false
defaultValueString := "" defaultValueString := ""
val := fv.FieldByName("Value")
if val.IsValid() { if val := fv.FieldByName("Value"); val.IsValid() {
needsPlaceholder = true needsPlaceholder = true
defaultValueString = fmt.Sprintf(" (default: %v)", val.Interface()) defaultValueString = fmt.Sprintf(" (default: %v)", val.Interface())
@@ -630,6 +759,17 @@ func stringifyIntSliceFlag(f IntSliceFlag) string {
return stringifySliceFlag(f.Usage, f.Name, defaultVals) return stringifySliceFlag(f.Usage, f.Name, defaultVals)
} }
func stringifyInt64SliceFlag(f Int64SliceFlag) string {
defaultVals := []string{}
if f.Value != nil && len(f.Value.Value()) > 0 {
for _, i := range f.Value.Value() {
defaultVals = append(defaultVals, fmt.Sprintf("%d", i))
}
}
return stringifySliceFlag(f.Usage, f.Name, defaultVals)
}
func stringifyStringSliceFlag(f StringSliceFlag) string { func stringifyStringSliceFlag(f StringSliceFlag) string {
defaultVals := []string{} defaultVals := []string{}
if f.Value != nil && len(f.Value.Value()) > 0 { if f.Value != nil && len(f.Value.Value()) > 0 {

627
vendor/github.com/urfave/cli/flag_generated.go generated vendored Normal file
View File

@@ -0,0 +1,627 @@
package cli
import (
"flag"
"strconv"
"time"
)
// WARNING: This file is generated!
// BoolFlag is a flag with type bool
type BoolFlag struct {
Name string
Usage string
EnvVar string
Hidden bool
Destination *bool
}
// String returns a readable representation of this value
// (for usage defaults)
func (f BoolFlag) String() string {
return FlagStringer(f)
}
// GetName returns the name of the flag
func (f BoolFlag) GetName() string {
return f.Name
}
// Bool looks up the value of a local BoolFlag, returns
// false if not found
func (c *Context) Bool(name string) bool {
return lookupBool(name, c.flagSet)
}
// GlobalBool looks up the value of a global BoolFlag, returns
// false if not found
func (c *Context) GlobalBool(name string) bool {
if fs := lookupGlobalFlagSet(name, c); fs != nil {
return lookupBool(name, fs)
}
return false
}
func lookupBool(name string, set *flag.FlagSet) bool {
f := set.Lookup(name)
if f != nil {
parsed, err := strconv.ParseBool(f.Value.String())
if err != nil {
return false
}
return parsed
}
return false
}
// BoolTFlag is a flag with type bool that is true by default
type BoolTFlag struct {
Name string
Usage string
EnvVar string
Hidden bool
Destination *bool
}
// String returns a readable representation of this value
// (for usage defaults)
func (f BoolTFlag) String() string {
return FlagStringer(f)
}
// GetName returns the name of the flag
func (f BoolTFlag) GetName() string {
return f.Name
}
// BoolT looks up the value of a local BoolTFlag, returns
// false if not found
func (c *Context) BoolT(name string) bool {
return lookupBoolT(name, c.flagSet)
}
// GlobalBoolT looks up the value of a global BoolTFlag, returns
// false if not found
func (c *Context) GlobalBoolT(name string) bool {
if fs := lookupGlobalFlagSet(name, c); fs != nil {
return lookupBoolT(name, fs)
}
return false
}
func lookupBoolT(name string, set *flag.FlagSet) bool {
f := set.Lookup(name)
if f != nil {
parsed, err := strconv.ParseBool(f.Value.String())
if err != nil {
return false
}
return parsed
}
return false
}
// DurationFlag is a flag with type time.Duration (see https://golang.org/pkg/time/#ParseDuration)
type DurationFlag struct {
Name string
Usage string
EnvVar string
Hidden bool
Value time.Duration
Destination *time.Duration
}
// String returns a readable representation of this value
// (for usage defaults)
func (f DurationFlag) String() string {
return FlagStringer(f)
}
// GetName returns the name of the flag
func (f DurationFlag) GetName() string {
return f.Name
}
// Duration looks up the value of a local DurationFlag, returns
// 0 if not found
func (c *Context) Duration(name string) time.Duration {
return lookupDuration(name, c.flagSet)
}
// GlobalDuration looks up the value of a global DurationFlag, returns
// 0 if not found
func (c *Context) GlobalDuration(name string) time.Duration {
if fs := lookupGlobalFlagSet(name, c); fs != nil {
return lookupDuration(name, fs)
}
return 0
}
func lookupDuration(name string, set *flag.FlagSet) time.Duration {
f := set.Lookup(name)
if f != nil {
parsed, err := time.ParseDuration(f.Value.String())
if err != nil {
return 0
}
return parsed
}
return 0
}
// Float64Flag is a flag with type float64
type Float64Flag struct {
Name string
Usage string
EnvVar string
Hidden bool
Value float64
Destination *float64
}
// String returns a readable representation of this value
// (for usage defaults)
func (f Float64Flag) String() string {
return FlagStringer(f)
}
// GetName returns the name of the flag
func (f Float64Flag) GetName() string {
return f.Name
}
// Float64 looks up the value of a local Float64Flag, returns
// 0 if not found
func (c *Context) Float64(name string) float64 {
return lookupFloat64(name, c.flagSet)
}
// GlobalFloat64 looks up the value of a global Float64Flag, returns
// 0 if not found
func (c *Context) GlobalFloat64(name string) float64 {
if fs := lookupGlobalFlagSet(name, c); fs != nil {
return lookupFloat64(name, fs)
}
return 0
}
func lookupFloat64(name string, set *flag.FlagSet) float64 {
f := set.Lookup(name)
if f != nil {
parsed, err := strconv.ParseFloat(f.Value.String(), 64)
if err != nil {
return 0
}
return parsed
}
return 0
}
// GenericFlag is a flag with type Generic
type GenericFlag struct {
Name string
Usage string
EnvVar string
Hidden bool
Value Generic
}
// String returns a readable representation of this value
// (for usage defaults)
func (f GenericFlag) String() string {
return FlagStringer(f)
}
// GetName returns the name of the flag
func (f GenericFlag) GetName() string {
return f.Name
}
// Generic looks up the value of a local GenericFlag, returns
// nil if not found
func (c *Context) Generic(name string) interface{} {
return lookupGeneric(name, c.flagSet)
}
// GlobalGeneric looks up the value of a global GenericFlag, returns
// nil if not found
func (c *Context) GlobalGeneric(name string) interface{} {
if fs := lookupGlobalFlagSet(name, c); fs != nil {
return lookupGeneric(name, fs)
}
return nil
}
func lookupGeneric(name string, set *flag.FlagSet) interface{} {
f := set.Lookup(name)
if f != nil {
parsed, err := f.Value, error(nil)
if err != nil {
return nil
}
return parsed
}
return nil
}
// Int64Flag is a flag with type int64
type Int64Flag struct {
Name string
Usage string
EnvVar string
Hidden bool
Value int64
Destination *int64
}
// String returns a readable representation of this value
// (for usage defaults)
func (f Int64Flag) String() string {
return FlagStringer(f)
}
// GetName returns the name of the flag
func (f Int64Flag) GetName() string {
return f.Name
}
// Int64 looks up the value of a local Int64Flag, returns
// 0 if not found
func (c *Context) Int64(name string) int64 {
return lookupInt64(name, c.flagSet)
}
// GlobalInt64 looks up the value of a global Int64Flag, returns
// 0 if not found
func (c *Context) GlobalInt64(name string) int64 {
if fs := lookupGlobalFlagSet(name, c); fs != nil {
return lookupInt64(name, fs)
}
return 0
}
func lookupInt64(name string, set *flag.FlagSet) int64 {
f := set.Lookup(name)
if f != nil {
parsed, err := strconv.ParseInt(f.Value.String(), 0, 64)
if err != nil {
return 0
}
return parsed
}
return 0
}
// IntFlag is a flag with type int
type IntFlag struct {
Name string
Usage string
EnvVar string
Hidden bool
Value int
Destination *int
}
// String returns a readable representation of this value
// (for usage defaults)
func (f IntFlag) String() string {
return FlagStringer(f)
}
// GetName returns the name of the flag
func (f IntFlag) GetName() string {
return f.Name
}
// Int looks up the value of a local IntFlag, returns
// 0 if not found
func (c *Context) Int(name string) int {
return lookupInt(name, c.flagSet)
}
// GlobalInt looks up the value of a global IntFlag, returns
// 0 if not found
func (c *Context) GlobalInt(name string) int {
if fs := lookupGlobalFlagSet(name, c); fs != nil {
return lookupInt(name, fs)
}
return 0
}
func lookupInt(name string, set *flag.FlagSet) int {
f := set.Lookup(name)
if f != nil {
parsed, err := strconv.ParseInt(f.Value.String(), 0, 64)
if err != nil {
return 0
}
return int(parsed)
}
return 0
}
// IntSliceFlag is a flag with type *IntSlice
type IntSliceFlag struct {
Name string
Usage string
EnvVar string
Hidden bool
Value *IntSlice
}
// String returns a readable representation of this value
// (for usage defaults)
func (f IntSliceFlag) String() string {
return FlagStringer(f)
}
// GetName returns the name of the flag
func (f IntSliceFlag) GetName() string {
return f.Name
}
// IntSlice looks up the value of a local IntSliceFlag, returns
// nil if not found
func (c *Context) IntSlice(name string) []int {
return lookupIntSlice(name, c.flagSet)
}
// GlobalIntSlice looks up the value of a global IntSliceFlag, returns
// nil if not found
func (c *Context) GlobalIntSlice(name string) []int {
if fs := lookupGlobalFlagSet(name, c); fs != nil {
return lookupIntSlice(name, fs)
}
return nil
}
func lookupIntSlice(name string, set *flag.FlagSet) []int {
f := set.Lookup(name)
if f != nil {
parsed, err := (f.Value.(*IntSlice)).Value(), error(nil)
if err != nil {
return nil
}
return parsed
}
return nil
}
// Int64SliceFlag is a flag with type *Int64Slice
type Int64SliceFlag struct {
Name string
Usage string
EnvVar string
Hidden bool
Value *Int64Slice
}
// String returns a readable representation of this value
// (for usage defaults)
func (f Int64SliceFlag) String() string {
return FlagStringer(f)
}
// GetName returns the name of the flag
func (f Int64SliceFlag) GetName() string {
return f.Name
}
// Int64Slice looks up the value of a local Int64SliceFlag, returns
// nil if not found
func (c *Context) Int64Slice(name string) []int64 {
return lookupInt64Slice(name, c.flagSet)
}
// GlobalInt64Slice looks up the value of a global Int64SliceFlag, returns
// nil if not found
func (c *Context) GlobalInt64Slice(name string) []int64 {
if fs := lookupGlobalFlagSet(name, c); fs != nil {
return lookupInt64Slice(name, fs)
}
return nil
}
func lookupInt64Slice(name string, set *flag.FlagSet) []int64 {
f := set.Lookup(name)
if f != nil {
parsed, err := (f.Value.(*Int64Slice)).Value(), error(nil)
if err != nil {
return nil
}
return parsed
}
return nil
}
// StringFlag is a flag with type string
type StringFlag struct {
Name string
Usage string
EnvVar string
Hidden bool
Value string
Destination *string
}
// String returns a readable representation of this value
// (for usage defaults)
func (f StringFlag) String() string {
return FlagStringer(f)
}
// GetName returns the name of the flag
func (f StringFlag) GetName() string {
return f.Name
}
// String looks up the value of a local StringFlag, returns
// "" if not found
func (c *Context) String(name string) string {
return lookupString(name, c.flagSet)
}
// GlobalString looks up the value of a global StringFlag, returns
// "" if not found
func (c *Context) GlobalString(name string) string {
if fs := lookupGlobalFlagSet(name, c); fs != nil {
return lookupString(name, fs)
}
return ""
}
func lookupString(name string, set *flag.FlagSet) string {
f := set.Lookup(name)
if f != nil {
parsed, err := f.Value.String(), error(nil)
if err != nil {
return ""
}
return parsed
}
return ""
}
// StringSliceFlag is a flag with type *StringSlice
type StringSliceFlag struct {
Name string
Usage string
EnvVar string
Hidden bool
Value *StringSlice
}
// String returns a readable representation of this value
// (for usage defaults)
func (f StringSliceFlag) String() string {
return FlagStringer(f)
}
// GetName returns the name of the flag
func (f StringSliceFlag) GetName() string {
return f.Name
}
// StringSlice looks up the value of a local StringSliceFlag, returns
// nil if not found
func (c *Context) StringSlice(name string) []string {
return lookupStringSlice(name, c.flagSet)
}
// GlobalStringSlice looks up the value of a global StringSliceFlag, returns
// nil if not found
func (c *Context) GlobalStringSlice(name string) []string {
if fs := lookupGlobalFlagSet(name, c); fs != nil {
return lookupStringSlice(name, fs)
}
return nil
}
func lookupStringSlice(name string, set *flag.FlagSet) []string {
f := set.Lookup(name)
if f != nil {
parsed, err := (f.Value.(*StringSlice)).Value(), error(nil)
if err != nil {
return nil
}
return parsed
}
return nil
}
// Uint64Flag is a flag with type uint64
type Uint64Flag struct {
Name string
Usage string
EnvVar string
Hidden bool
Value uint64
Destination *uint64
}
// String returns a readable representation of this value
// (for usage defaults)
func (f Uint64Flag) String() string {
return FlagStringer(f)
}
// GetName returns the name of the flag
func (f Uint64Flag) GetName() string {
return f.Name
}
// Uint64 looks up the value of a local Uint64Flag, returns
// 0 if not found
func (c *Context) Uint64(name string) uint64 {
return lookupUint64(name, c.flagSet)
}
// GlobalUint64 looks up the value of a global Uint64Flag, returns
// 0 if not found
func (c *Context) GlobalUint64(name string) uint64 {
if fs := lookupGlobalFlagSet(name, c); fs != nil {
return lookupUint64(name, fs)
}
return 0
}
func lookupUint64(name string, set *flag.FlagSet) uint64 {
f := set.Lookup(name)
if f != nil {
parsed, err := strconv.ParseUint(f.Value.String(), 0, 64)
if err != nil {
return 0
}
return parsed
}
return 0
}
// UintFlag is a flag with type uint
type UintFlag struct {
Name string
Usage string
EnvVar string
Hidden bool
Value uint
Destination *uint
}
// String returns a readable representation of this value
// (for usage defaults)
func (f UintFlag) String() string {
return FlagStringer(f)
}
// GetName returns the name of the flag
func (f UintFlag) GetName() string {
return f.Name
}
// Uint looks up the value of a local UintFlag, returns
// 0 if not found
func (c *Context) Uint(name string) uint {
return lookupUint(name, c.flagSet)
}
// GlobalUint looks up the value of a global UintFlag, returns
// 0 if not found
func (c *Context) GlobalUint(name string) uint {
if fs := lookupGlobalFlagSet(name, c); fs != nil {
return lookupUint(name, fs)
}
return 0
}
func lookupUint(name string, set *flag.FlagSet) uint {
f := set.Lookup(name)
if f != nil {
parsed, err := strconv.ParseUint(f.Value.String(), 0, 64)
if err != nil {
return 0
}
return uint(parsed)
}
return 0
}

136
vendor/github.com/urfave/cli/help.go generated vendored
View File

@@ -13,27 +13,31 @@ import (
// cli.go uses text/template to render templates. You can // cli.go uses text/template to render templates. You can
// render custom help text by setting this variable. // render custom help text by setting this variable.
var AppHelpTemplate = `NAME: var AppHelpTemplate = `NAME:
{{.Name}} - {{.Usage}} {{.Name}}{{if .Usage}} - {{.Usage}}{{end}}
USAGE: USAGE:
{{if .UsageText}}{{.UsageText}}{{else}}{{.HelpName}} {{if .VisibleFlags}}[global options]{{end}}{{if .Commands}} command [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{end}} {{if .UsageText}}{{.UsageText}}{{else}}{{.HelpName}} {{if .VisibleFlags}}[global options]{{end}}{{if .Commands}} command [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{end}}{{if .Version}}{{if not .HideVersion}}
{{if .Version}}{{if not .HideVersion}}
VERSION: VERSION:
{{.Version}} {{.Version}}{{end}}{{end}}{{if .Description}}
{{end}}{{end}}{{if len .Authors}}
AUTHOR(S): DESCRIPTION:
{{range .Authors}}{{.}}{{end}} {{.Description}}{{end}}{{if len .Authors}}
{{end}}{{if .VisibleCommands}}
AUTHOR{{with $length := len .Authors}}{{if ne 1 $length}}S{{end}}{{end}}:
{{range $index, $author := .Authors}}{{if $index}}
{{end}}{{$author}}{{end}}{{end}}{{if .VisibleCommands}}
COMMANDS:{{range .VisibleCategories}}{{if .Name}} COMMANDS:{{range .VisibleCategories}}{{if .Name}}
{{.Name}}:{{end}}{{range .VisibleCommands}} {{.Name}}:{{end}}{{range .VisibleCommands}}
{{.Name}}{{with .ShortName}}, {{.}}{{end}}{{"\t"}}{{.Usage}}{{end}} {{join .Names ", "}}{{"\t"}}{{.Usage}}{{end}}{{end}}{{end}}{{if .VisibleFlags}}
{{end}}{{end}}{{if .VisibleFlags}}
GLOBAL OPTIONS: GLOBAL OPTIONS:
{{range .VisibleFlags}}{{.}} {{range $index, $option := .VisibleFlags}}{{if $index}}
{{end}}{{end}}{{if .Copyright}} {{end}}{{$option}}{{end}}{{end}}{{if .Copyright}}
COPYRIGHT: COPYRIGHT:
{{.Copyright}} {{.Copyright}}{{end}}
{{end}}
` `
// CommandHelpTemplate is the text template for the command help topic. // CommandHelpTemplate is the text template for the command help topic.
@@ -43,7 +47,7 @@ var CommandHelpTemplate = `NAME:
{{.HelpName}} - {{.Usage}} {{.HelpName}} - {{.Usage}}
USAGE: USAGE:
{{.HelpName}}{{if .VisibleFlags}} [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{if .Category}} {{if .UsageText}}{{.UsageText}}{{else}}{{.HelpName}}{{if .VisibleFlags}} [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{end}}{{if .Category}}
CATEGORY: CATEGORY:
{{.Category}}{{end}}{{if .Description}} {{.Category}}{{end}}{{if .Description}}
@@ -60,14 +64,14 @@ OPTIONS:
// cli.go uses text/template to render templates. You can // cli.go uses text/template to render templates. You can
// render custom help text by setting this variable. // render custom help text by setting this variable.
var SubcommandHelpTemplate = `NAME: var SubcommandHelpTemplate = `NAME:
{{.HelpName}} - {{.Usage}} {{.HelpName}} - {{if .Description}}{{.Description}}{{else}}{{.Usage}}{{end}}
USAGE: USAGE:
{{.HelpName}} command{{if .VisibleFlags}} [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}} {{if .UsageText}}{{.UsageText}}{{else}}{{.HelpName}} command{{if .VisibleFlags}} [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{end}}
COMMANDS:{{range .VisibleCategories}}{{if .Name}} COMMANDS:{{range .VisibleCategories}}{{if .Name}}
{{.Name}}:{{end}}{{range .VisibleCommands}} {{.Name}}:{{end}}{{range .VisibleCommands}}
{{.Name}}{{with .ShortName}}, {{.}}{{end}}{{"\t"}}{{.Usage}}{{end}} {{join .Names ", "}}{{"\t"}}{{.Usage}}{{end}}
{{end}}{{if .VisibleFlags}} {{end}}{{if .VisibleFlags}}
OPTIONS: OPTIONS:
{{range .VisibleFlags}}{{.}} {{range .VisibleFlags}}{{.}}
@@ -108,17 +112,43 @@ var helpSubcommand = Command{
// Prints help for the App or Command // Prints help for the App or Command
type helpPrinter func(w io.Writer, templ string, data interface{}) type helpPrinter func(w io.Writer, templ string, data interface{})
// Prints help for the App or Command with custom template function.
type helpPrinterCustom func(w io.Writer, templ string, data interface{}, customFunc map[string]interface{})
// HelpPrinter is a function that writes the help output. If not set a default // HelpPrinter is a function that writes the help output. If not set a default
// is used. The function signature is: // is used. The function signature is:
// func(w io.Writer, templ string, data interface{}) // func(w io.Writer, templ string, data interface{})
var HelpPrinter helpPrinter = printHelp var HelpPrinter helpPrinter = printHelp
// HelpPrinterCustom is same as HelpPrinter but
// takes a custom function for template function map.
var HelpPrinterCustom helpPrinterCustom = printHelpCustom
// VersionPrinter prints the version for the App // VersionPrinter prints the version for the App
var VersionPrinter = printVersion var VersionPrinter = printVersion
// ShowAppHelpAndExit - Prints the list of subcommands for the app and exits with exit code.
func ShowAppHelpAndExit(c *Context, exitCode int) {
ShowAppHelp(c)
os.Exit(exitCode)
}
// ShowAppHelp is an action that displays the help. // ShowAppHelp is an action that displays the help.
func ShowAppHelp(c *Context) { func ShowAppHelp(c *Context) (err error) {
if c.App.CustomAppHelpTemplate == "" {
HelpPrinter(c.App.Writer, AppHelpTemplate, c.App) HelpPrinter(c.App.Writer, AppHelpTemplate, c.App)
return
}
customAppData := func() map[string]interface{} {
if c.App.ExtraInfo == nil {
return nil
}
return map[string]interface{}{
"ExtraInfo": c.App.ExtraInfo,
}
}
HelpPrinterCustom(c.App.Writer, c.App.CustomAppHelpTemplate, c.App, customAppData())
return nil
} }
// DefaultAppComplete prints the list of subcommands as the default app completion method // DefaultAppComplete prints the list of subcommands as the default app completion method
@@ -133,6 +163,12 @@ func DefaultAppComplete(c *Context) {
} }
} }
// ShowCommandHelpAndExit - exits with code after showing help
func ShowCommandHelpAndExit(c *Context, command string, code int) {
ShowCommandHelp(c, command)
os.Exit(code)
}
// ShowCommandHelp prints help for the given command // ShowCommandHelp prints help for the given command
func ShowCommandHelp(ctx *Context, command string) error { func ShowCommandHelp(ctx *Context, command string) error {
// show the subcommand help for a command with subcommands // show the subcommand help for a command with subcommands
@@ -143,7 +179,11 @@ func ShowCommandHelp(ctx *Context, command string) error {
for _, c := range ctx.App.Commands { for _, c := range ctx.App.Commands {
if c.HasName(command) { if c.HasName(command) {
if c.CustomHelpTemplate != "" {
HelpPrinterCustom(ctx.App.Writer, c.CustomHelpTemplate, c, nil)
} else {
HelpPrinter(ctx.App.Writer, CommandHelpTemplate, c) HelpPrinter(ctx.App.Writer, CommandHelpTemplate, c)
}
return nil return nil
} }
} }
@@ -186,12 +226,17 @@ func ShowCommandCompletions(ctx *Context, command string) {
} }
} }
func printHelp(out io.Writer, templ string, data interface{}) { func printHelpCustom(out io.Writer, templ string, data interface{}, customFunc map[string]interface{}) {
funcMap := template.FuncMap{ funcMap := template.FuncMap{
"join": strings.Join, "join": strings.Join,
} }
if customFunc != nil {
for key, value := range customFunc {
funcMap[key] = value
}
}
w := tabwriter.NewWriter(out, 0, 8, 1, '\t', 0) w := tabwriter.NewWriter(out, 1, 8, 2, ' ', 0)
t := template.Must(template.New("help").Funcs(funcMap).Parse(templ)) t := template.Must(template.New("help").Funcs(funcMap).Parse(templ))
err := t.Execute(w, data) err := t.Execute(w, data)
if err != nil { if err != nil {
@@ -205,10 +250,14 @@ func printHelp(out io.Writer, templ string, data interface{}) {
w.Flush() w.Flush()
} }
func printHelp(out io.Writer, templ string, data interface{}) {
printHelpCustom(out, templ, data, nil)
}
func checkVersion(c *Context) bool { func checkVersion(c *Context) bool {
found := false found := false
if VersionFlag.Name != "" { if VersionFlag.GetName() != "" {
eachName(VersionFlag.Name, func(name string) { eachName(VersionFlag.GetName(), func(name string) {
if c.GlobalBool(name) || c.Bool(name) { if c.GlobalBool(name) || c.Bool(name) {
found = true found = true
} }
@@ -219,8 +268,8 @@ func checkVersion(c *Context) bool {
func checkHelp(c *Context) bool { func checkHelp(c *Context) bool {
found := false found := false
if HelpFlag.Name != "" { if HelpFlag.GetName() != "" {
eachName(HelpFlag.Name, func(name string) { eachName(HelpFlag.GetName(), func(name string) {
if c.GlobalBool(name) || c.Bool(name) { if c.GlobalBool(name) || c.Bool(name) {
found = true found = true
} }
@@ -239,7 +288,7 @@ func checkCommandHelp(c *Context, name string) bool {
} }
func checkSubcommandHelp(c *Context) bool { func checkSubcommandHelp(c *Context) bool {
if c.GlobalBool("h") || c.GlobalBool("help") { if c.Bool("h") || c.Bool("help") {
ShowSubcommandHelp(c) ShowSubcommandHelp(c)
return true return true
} }
@@ -247,20 +296,43 @@ func checkSubcommandHelp(c *Context) bool {
return false return false
} }
func checkShellCompleteFlag(a *App, arguments []string) (bool, []string) {
if !a.EnableBashCompletion {
return false, arguments
}
pos := len(arguments) - 1
lastArg := arguments[pos]
if lastArg != "--"+BashCompletionFlag.GetName() {
return false, arguments
}
return true, arguments[:pos]
}
func checkCompletions(c *Context) bool { func checkCompletions(c *Context) bool {
if (c.GlobalBool(BashCompletionFlag.Name) || c.Bool(BashCompletionFlag.Name)) && c.App.EnableBashCompletion { if !c.shellComplete {
return false
}
if args := c.Args(); args.Present() {
name := args.First()
if cmd := c.App.Command(name); cmd != nil {
// let the command handle the completion
return false
}
}
ShowCompletions(c) ShowCompletions(c)
return true return true
} }
func checkCommandCompletions(c *Context, name string) bool {
if !c.shellComplete {
return false return false
} }
func checkCommandCompletions(c *Context, name string) bool {
if c.Bool(BashCompletionFlag.Name) && c.App.EnableBashCompletion {
ShowCommandCompletions(c, name) ShowCommandCompletions(c, name)
return true return true
} }
return false
}