aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--vendor.conf2
-rw-r--r--vendor/github.com/urfave/cli/README.md71
-rw-r--r--vendor/github.com/urfave/cli/app.go31
-rw-r--r--vendor/github.com/urfave/cli/category.go2
-rw-r--r--vendor/github.com/urfave/cli/command.go127
-rw-r--r--vendor/github.com/urfave/cli/context.go31
-rw-r--r--vendor/github.com/urfave/cli/flag.go323
-rw-r--r--vendor/github.com/urfave/cli/flag_generated.go53
-rw-r--r--vendor/github.com/urfave/cli/funcs.go16
-rw-r--r--vendor/github.com/urfave/cli/help.go1
-rw-r--r--vendor/github.com/urfave/cli/sort.go29
11 files changed, 440 insertions, 246 deletions
diff --git a/vendor.conf b/vendor.conf
index 592c1b64c..2b4fb5ebf 100644
--- a/vendor.conf
+++ b/vendor.conf
@@ -66,7 +66,7 @@ github.com/emicklei/go-restful ff4f55a206334ef123e4f79bbf348980da81ca46
github.com/emicklei/go-restful-swagger12 1.0.1
github.com/pkg/errors v0.8.0
github.com/godbus/dbus a389bdde4dd695d414e47b755e95e72b7826432c
-github.com/urfave/cli v1.20.0
+github.com/urfave/cli 119bb6564841921ce6f1401e0f5d75317bdd9f4d
github.com/vbatts/tar-split v0.10.2
github.com/renstrom/dedent v1.0.0
github.com/hpcloud/tail v1.0.0
diff --git a/vendor/github.com/urfave/cli/README.md b/vendor/github.com/urfave/cli/README.md
index 2bbbd8ea9..6096701d8 100644
--- a/vendor/github.com/urfave/cli/README.md
+++ b/vendor/github.com/urfave/cli/README.md
@@ -32,7 +32,9 @@ applications in an expressive way.
+ [Alternate Names](#alternate-names)
+ [Ordering](#ordering)
+ [Values from the Environment](#values-from-the-environment)
+ + [Values from files](#values-from-files)
+ [Values from alternate input sources (YAML, TOML, and others)](#values-from-alternate-input-sources-yaml-toml-and-others)
+ + [Precedence](#precedence)
* [Subcommands](#subcommands)
* [Subcommands categories](#subcommands-categories)
* [Exit code](#exit-code)
@@ -45,6 +47,7 @@ applications in an expressive way.
* [Version Flag](#version-flag)
+ [Customization](#customization-2)
+ [Full API Example](#full-api-example)
+ * [Combining short Bool options](#combining-short-bool-options)
- [Contribution Guidelines](#contribution-guidelines)
<!-- tocstop -->
@@ -586,6 +589,41 @@ func main() {
}
```
+#### Values from files
+
+You can also have the default value set from file via `FilePath`. e.g.
+
+<!-- {
+ "args": ["&#45;&#45;help"],
+ "output": "password for the mysql database"
+} -->
+``` go
+package main
+
+import (
+ "os"
+
+ "github.com/urfave/cli"
+)
+
+func main() {
+ app := cli.NewApp()
+
+ app.Flags = []cli.Flag {
+ cli.StringFlag{
+ Name: "password, p",
+ Usage: "password for the mysql database",
+ FilePath: "/etc/mysql/password",
+ },
+ }
+
+ app.Run(os.Args)
+}
+```
+
+Note that default values set from file (e.g. `FilePath`) take precedence over
+default values set from the enviornment (e.g. `EnvVar`).
+
#### Values from alternate input sources (YAML, TOML, and others)
There is a separate package altsrc that adds support for getting flag values
@@ -656,6 +694,15 @@ func main() {
}
```
+#### Precedence
+
+The precedence for flag value sources is as follows (highest to lowest):
+
+0. Command line flag value from user
+0. Environment variable (if specified)
+0. Configuration file (if specified)
+0. Default defined on the flag
+
### Subcommands
Subcommands can be defined for a more git-like command line app.
@@ -751,11 +798,11 @@ func main() {
},
{
Name: "add",
- Category: "template",
+ Category: "Template actions",
},
{
Name: "remove",
- Category: "template",
+ Category: "Template actions",
},
}
@@ -1364,6 +1411,26 @@ func wopAction(c *cli.Context) error {
}
```
+### Combining short Bool options
+
+Traditional use of boolean options using their shortnames look like this:
+```
+# cmd foobar -s -o
+```
+
+Suppose you want users to be able to combine your bool options with their shortname. This
+can be done using the **UseShortOptionHandling** bool in your commands. Suppose your program
+has a two bool flags such as *serve* and *option* with the short options of *-o* and
+*-s* respectively. With **UseShortOptionHandling** set to *true*, a user can use a syntax
+like:
+```
+# cmd foobar -so
+```
+
+If you enable the **UseShortOptionHandling*, then you must not use any flags that have a single
+leading *-* or this will result in failures. For example, **-option** can no longer be used. Flags
+with two leading dashes (such as **--options**) are still valid.
+
## Contribution Guidelines
Feel free to put up a pull request to fix a bug or maybe add a feature. I will
diff --git a/vendor/github.com/urfave/cli/app.go b/vendor/github.com/urfave/cli/app.go
index 51fc45d87..9add067b0 100644
--- a/vendor/github.com/urfave/cli/app.go
+++ b/vendor/github.com/urfave/cli/app.go
@@ -83,6 +83,9 @@ type App struct {
Writer io.Writer
// ErrWriter writes error output
ErrWriter io.Writer
+ // Execute this function to handle ExitErrors. If not provided, HandleExitCoder is provided to
+ // function as a default, so this is optional.
+ ExitErrHandler ExitErrHandlerFunc
// Other custom info
Metadata map[string]interface{}
// Carries a function which returns app specific info.
@@ -207,7 +210,7 @@ func (a *App) Run(arguments []string) (err error) {
if err != nil {
if a.OnUsageError != nil {
err := a.OnUsageError(context, err, false)
- HandleExitCoder(err)
+ a.handleExitCoder(context, err)
return err
}
fmt.Fprintf(a.Writer, "%s %s\n\n", "Incorrect Usage.", err.Error())
@@ -240,8 +243,9 @@ func (a *App) Run(arguments []string) (err error) {
if a.Before != nil {
beforeErr := a.Before(context)
if beforeErr != nil {
+ fmt.Fprintf(a.Writer, "%v\n\n", beforeErr)
ShowAppHelp(context)
- HandleExitCoder(beforeErr)
+ a.handleExitCoder(context, beforeErr)
err = beforeErr
return err
}
@@ -263,7 +267,7 @@ func (a *App) Run(arguments []string) (err error) {
// Run default Action
err = HandleAction(a.Action, context)
- HandleExitCoder(err)
+ a.handleExitCoder(context, err)
return err
}
@@ -330,7 +334,7 @@ func (a *App) RunAsSubcommand(ctx *Context) (err error) {
if err != nil {
if a.OnUsageError != nil {
err = a.OnUsageError(context, err, true)
- HandleExitCoder(err)
+ a.handleExitCoder(context, err)
return err
}
fmt.Fprintf(a.Writer, "%s %s\n\n", "Incorrect Usage.", err.Error())
@@ -352,7 +356,7 @@ func (a *App) RunAsSubcommand(ctx *Context) (err error) {
defer func() {
afterErr := a.After(context)
if afterErr != nil {
- HandleExitCoder(err)
+ a.handleExitCoder(context, err)
if err != nil {
err = NewMultiError(err, afterErr)
} else {
@@ -365,7 +369,7 @@ func (a *App) RunAsSubcommand(ctx *Context) (err error) {
if a.Before != nil {
beforeErr := a.Before(context)
if beforeErr != nil {
- HandleExitCoder(beforeErr)
+ a.handleExitCoder(context, beforeErr)
err = beforeErr
return err
}
@@ -383,7 +387,7 @@ func (a *App) RunAsSubcommand(ctx *Context) (err error) {
// Run default Action
err = HandleAction(a.Action, context)
- HandleExitCoder(err)
+ a.handleExitCoder(context, err)
return err
}
@@ -449,7 +453,6 @@ func (a *App) hasFlag(flag Flag) bool {
}
func (a *App) errWriter() io.Writer {
-
// When the app ErrWriter is nil use the package level one.
if a.ErrWriter == nil {
return ErrWriter
@@ -464,6 +467,14 @@ func (a *App) appendFlag(flag Flag) {
}
}
+func (a *App) handleExitCoder(context *Context, err error) {
+ if a.ExitErrHandler != nil {
+ a.ExitErrHandler(context, err)
+ } else {
+ HandleExitCoder(err)
+ }
+}
+
// Author represents someone who has contributed to a cli project.
type Author struct {
Name string // The Authors name
@@ -491,7 +502,7 @@ func HandleAction(action interface{}, context *Context) (err error) {
} else if a, ok := action.(func(*Context)); ok { // deprecated function signature
a(context)
return nil
- } else {
- return errInvalidActionType
}
+
+ return errInvalidActionType
}
diff --git a/vendor/github.com/urfave/cli/category.go b/vendor/github.com/urfave/cli/category.go
index 1a6055023..bf3c73c55 100644
--- a/vendor/github.com/urfave/cli/category.go
+++ b/vendor/github.com/urfave/cli/category.go
@@ -10,7 +10,7 @@ type CommandCategory struct {
}
func (c CommandCategories) Less(i, j int) bool {
- return c[i].Name < c[j].Name
+ return lexicographicLess(c[i].Name, c[j].Name)
}
func (c CommandCategories) Len() int {
diff --git a/vendor/github.com/urfave/cli/command.go b/vendor/github.com/urfave/cli/command.go
index 23de2944b..7d0357bd0 100644
--- a/vendor/github.com/urfave/cli/command.go
+++ b/vendor/github.com/urfave/cli/command.go
@@ -55,6 +55,10 @@ type Command struct {
HideHelp bool
// Boolean to hide this command from help or completion
Hidden bool
+ // Boolean to enable short-option handling so user can combine several
+ // single-character bool arguements into one
+ // i.e. foobar -o -v -> foobar -ov
+ UseShortOptionHandling bool
// Full name of command for help, defaults to full command name, including parent commands.
HelpName string
@@ -73,7 +77,7 @@ func (c CommandsByName) Len() int {
}
func (c CommandsByName) Less(i, j int) bool {
- return c[i].Name < c[j].Name
+ return lexicographicLess(c[i].Name, c[j].Name)
}
func (c CommandsByName) Swap(i, j int) {
@@ -111,43 +115,29 @@ func (c Command) Run(ctx *Context) (err error) {
return err
}
set.SetOutput(ioutil.Discard)
-
+ firstFlagIndex, terminatorIndex := getIndexes(ctx)
+ flagArgs, regularArgs := getAllArgs(ctx.Args(), firstFlagIndex, terminatorIndex)
+ if c.UseShortOptionHandling {
+ flagArgs = translateShortOptions(flagArgs)
+ }
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 if c.UseShortOptionHandling {
+ if terminatorIndex == -1 && firstFlagIndex > -1 {
+ // Handle shortname AND no options
+ err = set.Parse(append(regularArgs, flagArgs...))
+ } else {
+ // Handle shortname and options
+ err = set.Parse(flagArgs)
+ }
} else {
- err = set.Parse(ctx.Args().Tail())
+ err = set.Parse(append(regularArgs, flagArgs...))
}
nerr := normalizeFlags(c.Flags, set)
@@ -167,7 +157,7 @@ func (c Command) Run(ctx *Context) (err error) {
if err != nil {
if c.OnUsageError != nil {
err := c.OnUsageError(context, err, false)
- HandleExitCoder(err)
+ context.App.handleExitCoder(context, err)
return err
}
fmt.Fprintln(context.App.Writer, "Incorrect Usage:", err.Error())
@@ -184,7 +174,7 @@ func (c Command) Run(ctx *Context) (err error) {
defer func() {
afterErr := c.After(context)
if afterErr != nil {
- HandleExitCoder(err)
+ context.App.handleExitCoder(context, err)
if err != nil {
err = NewMultiError(err, afterErr)
} else {
@@ -198,7 +188,7 @@ func (c Command) Run(ctx *Context) (err error) {
err = c.Before(context)
if err != nil {
ShowCommandHelp(context, c.Name)
- HandleExitCoder(err)
+ context.App.handleExitCoder(context, err)
return err
}
}
@@ -210,11 +200,82 @@ func (c Command) Run(ctx *Context) (err error) {
err = HandleAction(c.Action, context)
if err != nil {
- HandleExitCoder(err)
+ context.App.handleExitCoder(context, err)
}
return err
}
+func getIndexes(ctx *Context) (int, int) {
+ 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 len(ctx.Args()) > 0 && !strings.HasPrefix(ctx.Args()[0], "-") && firstFlagIndex == -1 {
+ return -1, -1
+ }
+
+ return firstFlagIndex, terminatorIndex
+
+}
+
+// copyStringslice takes a string slice and copies it
+func copyStringSlice(slice []string, start, end int) []string {
+ newSlice := make([]string, end-start)
+ copy(newSlice, slice[start:end])
+ return newSlice
+}
+
+// getAllArgs extracts and returns two string slices representing
+// regularArgs and flagArgs
+func getAllArgs(args []string, firstFlagIndex, terminatorIndex int) ([]string, []string) {
+ var regularArgs []string
+ // if there are no options, the we set the index to 1 manually
+ if firstFlagIndex == -1 {
+ firstFlagIndex = 1
+ regularArgs = copyStringSlice(args, 0, len(args))
+ } else {
+ regularArgs = copyStringSlice(args, 1, firstFlagIndex)
+ }
+ var flagArgs []string
+ // a flag terminatorIndex was found in the input. we need to collect
+ // flagArgs based on it.
+ if terminatorIndex > -1 {
+ flagArgs = copyStringSlice(args, firstFlagIndex, terminatorIndex)
+ additionalRegularArgs := copyStringSlice(args, terminatorIndex, len(args))
+ regularArgs = append(regularArgs, additionalRegularArgs...)
+ for _, i := range additionalRegularArgs {
+ regularArgs = append(regularArgs, i)
+ }
+ } else {
+ flagArgs = args[firstFlagIndex:]
+ }
+ return flagArgs, regularArgs
+}
+
+func translateShortOptions(flagArgs Args) []string {
+ // separate combined flags
+ var flagArgsSeparated []string
+ for _, flagArg := range flagArgs {
+ if strings.HasPrefix(flagArg, "-") && strings.HasPrefix(flagArg, "--") == false && len(flagArg) > 2 {
+ for _, flagChar := range flagArg[1:] {
+ flagArgsSeparated = append(flagArgsSeparated, "-"+string(flagChar))
+ }
+ } else {
+ flagArgsSeparated = append(flagArgsSeparated, flagArg)
+ }
+ }
+ return flagArgsSeparated
+}
+
// Names returns the names including short names and aliases.
func (c Command) Names() []string {
names := []string{c.Name}
diff --git a/vendor/github.com/urfave/cli/context.go b/vendor/github.com/urfave/cli/context.go
index db94191e2..552ee7405 100644
--- a/vendor/github.com/urfave/cli/context.go
+++ b/vendor/github.com/urfave/cli/context.go
@@ -3,6 +3,7 @@ package cli
import (
"errors"
"flag"
+ "os"
"reflect"
"strings"
"syscall"
@@ -73,7 +74,7 @@ func (c *Context) IsSet(name string) bool {
// 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.
+ // variables is available.
//
// See https://github.com/urfave/cli/issues/294 for additional discussion
flags := c.Command.Flags
@@ -93,18 +94,26 @@ func (c *Context) IsSet(name string) bool {
val = val.Elem()
}
- envVarValue := val.FieldByName("EnvVar")
- if !envVarValue.IsValid() {
- return
+ filePathValue := val.FieldByName("FilePath")
+ if filePathValue.IsValid() {
+ eachName(filePathValue.String(), func(filePath string) {
+ if _, err := os.Stat(filePath); err == nil {
+ c.setFlags[name] = true
+ return
+ }
+ })
}
- eachName(envVarValue.String(), func(envVar string) {
- envVar = strings.TrimSpace(envVar)
- if _, ok := syscall.Getenv(envVar); ok {
- c.setFlags[name] = true
- return
- }
- })
+ envVarValue := val.FieldByName("EnvVar")
+ if envVarValue.IsValid() {
+ eachName(envVarValue.String(), func(envVar string) {
+ envVar = strings.TrimSpace(envVar)
+ if _, ok := syscall.Getenv(envVar); ok {
+ c.setFlags[name] = true
+ return
+ }
+ })
+ }
})
}
}
diff --git a/vendor/github.com/urfave/cli/flag.go b/vendor/github.com/urfave/cli/flag.go
index 877ff3523..d4a4d41a2 100644
--- a/vendor/github.com/urfave/cli/flag.go
+++ b/vendor/github.com/urfave/cli/flag.go
@@ -3,6 +3,7 @@ package cli
import (
"flag"
"fmt"
+ "io/ioutil"
"reflect"
"runtime"
"strconv"
@@ -37,6 +38,18 @@ var HelpFlag Flag = BoolFlag{
// to display a flag.
var FlagStringer FlagStringFunc = stringifyFlag
+// FlagNamePrefixer converts a full flag name and its placeholder into the help
+// message flag prefix. This is used by the default FlagStringer.
+var FlagNamePrefixer FlagNamePrefixFunc = prefixedNames
+
+// FlagEnvHinter annotates flag help message with the environment variable
+// details. This is used by the default FlagStringer.
+var FlagEnvHinter FlagEnvHintFunc = withEnvHint
+
+// FlagFileHinter annotates flag help message with the environment variable
+// details. This is used by the default FlagStringer.
+var FlagFileHinter FlagFileHintFunc = withFileHint
+
// FlagsByName is a slice of Flag.
type FlagsByName []Flag
@@ -45,7 +58,7 @@ func (f FlagsByName) Len() int {
}
func (f FlagsByName) Less(i, j int) bool {
- return f[i].GetName() < f[j].GetName()
+ return lexicographicLess(f[i].GetName(), f[j].GetName())
}
func (f FlagsByName) Swap(i, j int) {
@@ -112,15 +125,9 @@ func (f GenericFlag) Apply(set *flag.FlagSet) {
// provided by the user for parsing by the flag
func (f GenericFlag) ApplyWithError(set *flag.FlagSet) error {
val := f.Value
- if f.EnvVar != "" {
- for _, envVar := range strings.Split(f.EnvVar, ",") {
- envVar = strings.TrimSpace(envVar)
- if envVal, ok := syscall.Getenv(envVar); ok {
- 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
- }
+ if fileEnvVal, ok := flagFromFileEnv(f.FilePath, f.EnvVar); ok {
+ if err := val.Set(fileEnvVal); err != nil {
+ return fmt.Errorf("could not parse %s as value for flag %s: %s", fileEnvVal, f.Name, err)
}
}
@@ -163,21 +170,19 @@ func (f StringSliceFlag) Apply(set *flag.FlagSet) {
// ApplyWithError populates the flag given the flag set and environment
func (f StringSliceFlag) 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 := &StringSlice{}
- 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 string value for flag %s: %s", envVal, f.Name, err)
- }
- }
- f.Value = newVal
- break
+ if envVal, ok := flagFromFileEnv(f.FilePath, f.EnvVar); ok {
+ newVal := &StringSlice{}
+ 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 string value for flag %s: %s", envVal, f.Name, err)
}
}
+ if f.Value == nil {
+ f.Value = newVal
+ } else {
+ *f.Value = *newVal
+ }
}
eachName(f.Name, func(name string) {
@@ -226,21 +231,19 @@ func (f IntSliceFlag) Apply(set *flag.FlagSet) {
// ApplyWithError populates the flag given the flag set and environment
func (f IntSliceFlag) 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 := &IntSlice{}
- 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 int slice value for flag %s: %s", envVal, f.Name, err)
- }
- }
- f.Value = newVal
- break
+ if envVal, ok := flagFromFileEnv(f.FilePath, f.EnvVar); ok {
+ newVal := &IntSlice{}
+ 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 int slice value for flag %s: %s", envVal, f.Name, err)
}
}
+ if f.Value == nil {
+ f.Value = newVal
+ } else {
+ *f.Value = *newVal
+ }
}
eachName(f.Name, func(name string) {
@@ -289,21 +292,19 @@ func (f Int64SliceFlag) Apply(set *flag.FlagSet) {
// 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
+ if envVal, ok := flagFromFileEnv(f.FilePath, f.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)
}
}
+ if f.Value == nil {
+ f.Value = newVal
+ } else {
+ *f.Value = *newVal
+ }
}
eachName(f.Name, func(name string) {
@@ -324,23 +325,15 @@ func (f BoolFlag) Apply(set *flag.FlagSet) {
// ApplyWithError populates the flag given the flag set and environment
func (f BoolFlag) ApplyWithError(set *flag.FlagSet) error {
val := false
- if f.EnvVar != "" {
- for _, envVar := range strings.Split(f.EnvVar, ",") {
- envVar = strings.TrimSpace(envVar)
- if envVal, ok := syscall.Getenv(envVar); ok {
- if envVal == "" {
- val = false
- 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
+ if envVal, ok := flagFromFileEnv(f.FilePath, f.EnvVar); ok {
+ if envVal == "" {
+ val = false
+ } else {
+ 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
}
}
@@ -364,23 +357,16 @@ func (f BoolTFlag) Apply(set *flag.FlagSet) {
// ApplyWithError populates the flag given the flag set and environment
func (f BoolTFlag) ApplyWithError(set *flag.FlagSet) error {
val := true
- if f.EnvVar != "" {
- for _, envVar := range strings.Split(f.EnvVar, ",") {
- envVar = strings.TrimSpace(envVar)
- if envVal, ok := syscall.Getenv(envVar); ok {
- if envVal == "" {
- val = false
- 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
+ if envVal, ok := flagFromFileEnv(f.FilePath, f.EnvVar); ok {
+ if envVal == "" {
+ val = false
+ } else {
+ 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
}
}
@@ -403,14 +389,8 @@ func (f StringFlag) Apply(set *flag.FlagSet) {
// ApplyWithError populates the flag given the flag set and environment
func (f StringFlag) 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 {
- f.Value = envVal
- break
- }
- }
+ if envVal, ok := flagFromFileEnv(f.FilePath, f.EnvVar); ok {
+ f.Value = envVal
}
eachName(f.Name, func(name string) {
@@ -432,18 +412,12 @@ func (f IntFlag) Apply(set *flag.FlagSet) {
// ApplyWithError populates the flag given the flag set and environment
func (f IntFlag) 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.ParseInt(envVal, 0, 64)
- 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)
- break
- }
+ if envVal, ok := flagFromFileEnv(f.FilePath, f.EnvVar); ok {
+ envValInt, err := strconv.ParseInt(envVal, 0, 64)
+ 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)
}
eachName(f.Name, func(name string) {
@@ -465,19 +439,13 @@ func (f Int64Flag) Apply(set *flag.FlagSet) {
// ApplyWithError populates the flag given the flag set and environment
func (f Int64Flag) 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.ParseInt(envVal, 0, 64)
- if err != nil {
- return fmt.Errorf("could not parse %s as int value for flag %s: %s", envVal, f.Name, err)
- }
-
- f.Value = envValInt
- break
- }
+ if envVal, ok := flagFromFileEnv(f.FilePath, f.EnvVar); ok {
+ envValInt, err := strconv.ParseInt(envVal, 0, 64)
+ if err != nil {
+ return fmt.Errorf("could not parse %s as int value for flag %s: %s", envVal, f.Name, err)
}
+
+ f.Value = envValInt
}
eachName(f.Name, func(name string) {
@@ -499,19 +467,13 @@ func (f UintFlag) Apply(set *flag.FlagSet) {
// 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
- }
+ if envVal, ok := flagFromFileEnv(f.FilePath, f.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)
}
eachName(f.Name, func(name string) {
@@ -533,19 +495,13 @@ func (f Uint64Flag) Apply(set *flag.FlagSet) {
// 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
- }
+ if envVal, ok := flagFromFileEnv(f.FilePath, f.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)
}
eachName(f.Name, func(name string) {
@@ -567,19 +523,13 @@ func (f DurationFlag) Apply(set *flag.FlagSet) {
// 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
- }
+ if envVal, ok := flagFromFileEnv(f.FilePath, f.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
}
eachName(f.Name, func(name string) {
@@ -601,19 +551,13 @@ func (f Float64Flag) Apply(set *flag.FlagSet) {
// ApplyWithError populates the flag given the flag set and environment
func (f Float64Flag) 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 {
- envValFloat, err := strconv.ParseFloat(envVal, 10)
- if err != nil {
- return fmt.Errorf("could not parse %s as float64 value for flag %s: %s", envVal, f.Name, err)
- }
-
- f.Value = float64(envValFloat)
- break
- }
+ if envVal, ok := flagFromFileEnv(f.FilePath, f.EnvVar); ok {
+ envValFloat, err := strconv.ParseFloat(envVal, 10)
+ if err != nil {
+ return fmt.Errorf("could not parse %s as float64 value for flag %s: %s", envVal, f.Name, err)
}
+
+ f.Value = float64(envValFloat)
}
eachName(f.Name, func(name string) {
@@ -697,6 +641,14 @@ func withEnvHint(envVar, str string) string {
return str + envText
}
+func withFileHint(filePath, str string) string {
+ fileText := ""
+ if filePath != "" {
+ fileText = fmt.Sprintf(" [%s]", filePath)
+ }
+ return str + fileText
+}
+
func flagValue(f Flag) reflect.Value {
fv := reflect.ValueOf(f)
for fv.Kind() == reflect.Ptr {
@@ -710,14 +662,29 @@ func stringifyFlag(f Flag) string {
switch f.(type) {
case IntSliceFlag:
- return withEnvHint(fv.FieldByName("EnvVar").String(),
- stringifyIntSliceFlag(f.(IntSliceFlag)))
+ return FlagFileHinter(
+ fv.FieldByName("FilePath").String(),
+ FlagEnvHinter(
+ fv.FieldByName("EnvVar").String(),
+ stringifyIntSliceFlag(f.(IntSliceFlag)),
+ ),
+ )
case Int64SliceFlag:
- return withEnvHint(fv.FieldByName("EnvVar").String(),
- stringifyInt64SliceFlag(f.(Int64SliceFlag)))
+ return FlagFileHinter(
+ fv.FieldByName("FilePath").String(),
+ FlagEnvHinter(
+ fv.FieldByName("EnvVar").String(),
+ stringifyInt64SliceFlag(f.(Int64SliceFlag)),
+ ),
+ )
case StringSliceFlag:
- return withEnvHint(fv.FieldByName("EnvVar").String(),
- stringifyStringSliceFlag(f.(StringSliceFlag)))
+ return FlagFileHinter(
+ fv.FieldByName("FilePath").String(),
+ FlagEnvHinter(
+ fv.FieldByName("EnvVar").String(),
+ stringifyStringSliceFlag(f.(StringSliceFlag)),
+ ),
+ )
}
placeholder, usage := unquoteUsage(fv.FieldByName("Usage").String())
@@ -744,8 +711,13 @@ func stringifyFlag(f Flag) string {
usageWithDefault := strings.TrimSpace(fmt.Sprintf("%s%s", usage, defaultValueString))
- return withEnvHint(fv.FieldByName("EnvVar").String(),
- fmt.Sprintf("%s\t%s", prefixedNames(fv.FieldByName("Name").String(), placeholder), usageWithDefault))
+ return FlagFileHinter(
+ fv.FieldByName("FilePath").String(),
+ FlagEnvHinter(
+ fv.FieldByName("EnvVar").String(),
+ fmt.Sprintf("%s\t%s", FlagNamePrefixer(fv.FieldByName("Name").String(), placeholder), usageWithDefault),
+ ),
+ )
}
func stringifyIntSliceFlag(f IntSliceFlag) string {
@@ -795,5 +767,20 @@ func stringifySliceFlag(usage, name string, defaultVals []string) string {
}
usageWithDefault := strings.TrimSpace(fmt.Sprintf("%s%s", usage, defaultVal))
- return fmt.Sprintf("%s\t%s", prefixedNames(name, placeholder), usageWithDefault)
+ return fmt.Sprintf("%s\t%s", FlagNamePrefixer(name, placeholder), usageWithDefault)
+}
+
+func flagFromFileEnv(filePath, envName string) (val string, ok bool) {
+ for _, envVar := range strings.Split(envName, ",") {
+ envVar = strings.TrimSpace(envVar)
+ if envVal, ok := syscall.Getenv(envVar); ok {
+ return envVal, true
+ }
+ }
+ for _, fileVar := range strings.Split(filePath, ",") {
+ if data, err := ioutil.ReadFile(fileVar); err == nil {
+ return string(data), true
+ }
+ }
+ return "", false
}
diff --git a/vendor/github.com/urfave/cli/flag_generated.go b/vendor/github.com/urfave/cli/flag_generated.go
index 491b61956..001576c8b 100644
--- a/vendor/github.com/urfave/cli/flag_generated.go
+++ b/vendor/github.com/urfave/cli/flag_generated.go
@@ -13,6 +13,7 @@ type BoolFlag struct {
Name string
Usage string
EnvVar string
+ FilePath string
Hidden bool
Destination *bool
}
@@ -60,6 +61,7 @@ type BoolTFlag struct {
Name string
Usage string
EnvVar string
+ FilePath string
Hidden bool
Destination *bool
}
@@ -107,6 +109,7 @@ type DurationFlag struct {
Name string
Usage string
EnvVar string
+ FilePath string
Hidden bool
Value time.Duration
Destination *time.Duration
@@ -155,6 +158,7 @@ type Float64Flag struct {
Name string
Usage string
EnvVar string
+ FilePath string
Hidden bool
Value float64
Destination *float64
@@ -200,11 +204,12 @@ func lookupFloat64(name string, set *flag.FlagSet) float64 {
// GenericFlag is a flag with type Generic
type GenericFlag struct {
- Name string
- Usage string
- EnvVar string
- Hidden bool
- Value Generic
+ Name string
+ Usage string
+ EnvVar string
+ FilePath string
+ Hidden bool
+ Value Generic
}
// String returns a readable representation of this value
@@ -250,6 +255,7 @@ type Int64Flag struct {
Name string
Usage string
EnvVar string
+ FilePath string
Hidden bool
Value int64
Destination *int64
@@ -298,6 +304,7 @@ type IntFlag struct {
Name string
Usage string
EnvVar string
+ FilePath string
Hidden bool
Value int
Destination *int
@@ -343,11 +350,12 @@ func lookupInt(name string, set *flag.FlagSet) int {
// IntSliceFlag is a flag with type *IntSlice
type IntSliceFlag struct {
- Name string
- Usage string
- EnvVar string
- Hidden bool
- Value *IntSlice
+ Name string
+ Usage string
+ EnvVar string
+ FilePath string
+ Hidden bool
+ Value *IntSlice
}
// String returns a readable representation of this value
@@ -390,11 +398,12 @@ func lookupIntSlice(name string, set *flag.FlagSet) []int {
// Int64SliceFlag is a flag with type *Int64Slice
type Int64SliceFlag struct {
- Name string
- Usage string
- EnvVar string
- Hidden bool
- Value *Int64Slice
+ Name string
+ Usage string
+ EnvVar string
+ FilePath string
+ Hidden bool
+ Value *Int64Slice
}
// String returns a readable representation of this value
@@ -440,6 +449,7 @@ type StringFlag struct {
Name string
Usage string
EnvVar string
+ FilePath string
Hidden bool
Value string
Destination *string
@@ -485,11 +495,12 @@ func lookupString(name string, set *flag.FlagSet) string {
// StringSliceFlag is a flag with type *StringSlice
type StringSliceFlag struct {
- Name string
- Usage string
- EnvVar string
- Hidden bool
- Value *StringSlice
+ Name string
+ Usage string
+ EnvVar string
+ FilePath string
+ Hidden bool
+ Value *StringSlice
}
// String returns a readable representation of this value
@@ -535,6 +546,7 @@ type Uint64Flag struct {
Name string
Usage string
EnvVar string
+ FilePath string
Hidden bool
Value uint64
Destination *uint64
@@ -583,6 +595,7 @@ type UintFlag struct {
Name string
Usage string
EnvVar string
+ FilePath string
Hidden bool
Value uint
Destination *uint
diff --git a/vendor/github.com/urfave/cli/funcs.go b/vendor/github.com/urfave/cli/funcs.go
index cba5e6cb0..0036b1130 100644
--- a/vendor/github.com/urfave/cli/funcs.go
+++ b/vendor/github.com/urfave/cli/funcs.go
@@ -23,6 +23,22 @@ type CommandNotFoundFunc func(*Context, string)
// is displayed and the execution is interrupted.
type OnUsageErrorFunc func(context *Context, err error, isSubcommand bool) error
+// ExitErrHandlerFunc is executed if provided in order to handle ExitError values
+// returned by Actions and Before/After functions.
+type ExitErrHandlerFunc func(context *Context, err error)
+
// FlagStringFunc is used by the help generation to display a flag, which is
// expected to be a single line.
type FlagStringFunc func(Flag) string
+
+// FlagNamePrefixFunc is used by the default FlagStringFunc to create prefix
+// text for a flag's full name.
+type FlagNamePrefixFunc func(fullName, placeholder string) string
+
+// FlagEnvHintFunc is used by the default FlagStringFunc to annotate flag help
+// with the environment variable details.
+type FlagEnvHintFunc func(envVar, str string) string
+
+// FlagFileHintFunc is used by the default FlagStringFunc to annotate flag help
+// with the file path details.
+type FlagFileHintFunc func(filePath, str string) string
diff --git a/vendor/github.com/urfave/cli/help.go b/vendor/github.com/urfave/cli/help.go
index 57ec98d58..ed084fc1d 100644
--- a/vendor/github.com/urfave/cli/help.go
+++ b/vendor/github.com/urfave/cli/help.go
@@ -29,6 +29,7 @@ AUTHOR{{with $length := len .Authors}}{{if ne 1 $length}}S{{end}}{{end}}:
{{end}}{{$author}}{{end}}{{end}}{{if .VisibleCommands}}
COMMANDS:{{range .VisibleCategories}}{{if .Name}}
+
{{.Name}}:{{end}}{{range .VisibleCommands}}
{{join .Names ", "}}{{"\t"}}{{.Usage}}{{end}}{{end}}{{end}}{{if .VisibleFlags}}
diff --git a/vendor/github.com/urfave/cli/sort.go b/vendor/github.com/urfave/cli/sort.go
new file mode 100644
index 000000000..23d1c2f77
--- /dev/null
+++ b/vendor/github.com/urfave/cli/sort.go
@@ -0,0 +1,29 @@
+package cli
+
+import "unicode"
+
+// lexicographicLess compares strings alphabetically considering case.
+func lexicographicLess(i, j string) bool {
+ iRunes := []rune(i)
+ jRunes := []rune(j)
+
+ lenShared := len(iRunes)
+ if lenShared > len(jRunes) {
+ lenShared = len(jRunes)
+ }
+
+ for index := 0; index < lenShared; index++ {
+ ir := iRunes[index]
+ jr := jRunes[index]
+
+ if lir, ljr := unicode.ToLower(ir), unicode.ToLower(jr); lir != ljr {
+ return lir < ljr
+ }
+
+ if ir != jr {
+ return ir < jr
+ }
+ }
+
+ return i < j
+}