Merge branch 'master' into master

This commit is contained in:
Tyler Davis 2017-10-13 12:05:14 -07:00 committed by GitHub
commit 40263f4d6a
9 changed files with 117 additions and 26 deletions

View File

@ -22,15 +22,15 @@ func nestedVal(name string, tree map[interface{}]interface{}) (interface{}, bool
if sections := strings.Split(name, "."); len(sections) > 1 {
node := tree
for _, section := range sections[:len(sections)-1] {
if child, ok := node[section]; !ok {
child, ok := node[section]
if !ok {
return nil, false
} else {
if ctype, ok := child.(map[interface{}]interface{}); !ok {
return nil, false
} else {
node = ctype
}
}
ctype, ok := child.(map[interface{}]interface{})
if !ok {
return nil, false
}
node = ctype
}
if val, ok := node[sections[len(sections)-1]]; ok {
return val, true

View File

@ -66,9 +66,9 @@ func unmarshalMap(i interface{}) (ret map[interface{}]interface{}, err error) {
return ret, nil
}
func (self *tomlMap) UnmarshalTOML(i interface{}) error {
func (tm *tomlMap) UnmarshalTOML(i interface{}) error {
if tmp, err := unmarshalMap(i); err == nil {
self.Map = tmp
tm.Map = tmp
} else {
return err
}

View File

@ -86,7 +86,7 @@ func loadDataFrom(filePath string) ([]byte, error) {
return nil, fmt.Errorf("Cannot read from file: '%s' because it does not exist.", filePath)
}
return ioutil.ReadFile(filePath)
} else {
return nil, fmt.Errorf("unable to determine how to load from path %s", filePath)
}
return nil, fmt.Errorf("unable to determine how to load from path %s", filePath)
}

4
app.go
View File

@ -503,7 +503,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
}

View File

@ -497,7 +497,6 @@ func TestApp_Float64Flag(t *testing.T) {
}
func TestApp_ParseSliceFlags(t *testing.T) {
var parsedOption, firstArg string
var parsedIntSlice []int
var parsedStringSlice []string
@ -511,8 +510,6 @@ func TestApp_ParseSliceFlags(t *testing.T) {
Action: func(c *Context) error {
parsedIntSlice = c.IntSlice("p")
parsedStringSlice = c.StringSlice("ip")
parsedOption = c.String("option")
firstArg = c.Args().First()
return nil
},
}

View File

@ -73,7 +73,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

20
flag.go
View File

@ -37,6 +37,14 @@ 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
// FlagsByName is a slice of Flag.
type FlagsByName []Flag
@ -710,13 +718,13 @@ func stringifyFlag(f Flag) string {
switch f.(type) {
case IntSliceFlag:
return withEnvHint(fv.FieldByName("EnvVar").String(),
return FlagEnvHinter(fv.FieldByName("EnvVar").String(),
stringifyIntSliceFlag(f.(IntSliceFlag)))
case Int64SliceFlag:
return withEnvHint(fv.FieldByName("EnvVar").String(),
return FlagEnvHinter(fv.FieldByName("EnvVar").String(),
stringifyInt64SliceFlag(f.(Int64SliceFlag)))
case StringSliceFlag:
return withEnvHint(fv.FieldByName("EnvVar").String(),
return FlagEnvHinter(fv.FieldByName("EnvVar").String(),
stringifyStringSliceFlag(f.(StringSliceFlag)))
}
@ -744,8 +752,8 @@ 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 FlagEnvHinter(fv.FieldByName("EnvVar").String(),
fmt.Sprintf("%s\t%s", FlagNamePrefixer(fv.FieldByName("Name").String(), placeholder), usageWithDefault))
}
func stringifyIntSliceFlag(f IntSliceFlag) string {
@ -795,5 +803,5 @@ 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)
}

View File

@ -158,6 +158,83 @@ func TestStringFlagWithEnvVarHelpOutput(t *testing.T) {
}
}
var prefixStringFlagTests = []struct {
name string
usage string
value string
prefixer FlagNamePrefixFunc
expected string
}{
{"foo", "", "", func(a, b string) string {
return fmt.Sprintf("name: %s, ph: %s", a, b)
}, "name: foo, ph: value\t"},
{"f", "", "", func(a, b string) string {
return fmt.Sprintf("name: %s, ph: %s", a, b)
}, "name: f, ph: value\t"},
{"f", "The total `foo` desired", "all", func(a, b string) string {
return fmt.Sprintf("name: %s, ph: %s", a, b)
}, "name: f, ph: foo\tThe total foo desired (default: \"all\")"},
{"test", "", "Something", func(a, b string) string {
return fmt.Sprintf("name: %s, ph: %s", a, b)
}, "name: test, ph: value\t(default: \"Something\")"},
{"config,c", "Load configuration from `FILE`", "", func(a, b string) string {
return fmt.Sprintf("name: %s, ph: %s", a, b)
}, "name: config,c, ph: FILE\tLoad configuration from FILE"},
{"config,c", "Load configuration from `CONFIG`", "config.json", func(a, b string) string {
return fmt.Sprintf("name: %s, ph: %s", a, b)
}, "name: config,c, ph: CONFIG\tLoad configuration from CONFIG (default: \"config.json\")"},
}
func TestFlagNamePrefixer(t *testing.T) {
defer func() {
FlagNamePrefixer = prefixedNames
}()
for _, test := range prefixStringFlagTests {
FlagNamePrefixer = test.prefixer
flag := StringFlag{Name: test.name, Usage: test.usage, Value: test.value}
output := flag.String()
if output != test.expected {
t.Errorf("%q does not match %q", output, test.expected)
}
}
}
var envHintFlagTests = []struct {
name string
env string
hinter FlagEnvHintFunc
expected string
}{
{"foo", "", func(a, b string) string {
return fmt.Sprintf("env: %s, str: %s", a, b)
}, "env: , str: --foo value\t"},
{"f", "", func(a, b string) string {
return fmt.Sprintf("env: %s, str: %s", a, b)
}, "env: , str: -f value\t"},
{"foo", "ENV_VAR", func(a, b string) string {
return fmt.Sprintf("env: %s, str: %s", a, b)
}, "env: ENV_VAR, str: --foo value\t"},
{"f", "ENV_VAR", func(a, b string) string {
return fmt.Sprintf("env: %s, str: %s", a, b)
}, "env: ENV_VAR, str: -f value\t"},
}
func TestFlagEnvHinter(t *testing.T) {
defer func() {
FlagEnvHinter = withEnvHint
}()
for _, test := range envHintFlagTests {
FlagEnvHinter = test.hinter
flag := StringFlag{Name: test.name, EnvVar: test.env}
output := flag.String()
if output != test.expected {
t.Errorf("%q does not match %q", output, test.expected)
}
}
}
var stringSliceFlagTests = []struct {
name string
value *StringSlice

View File

@ -23,10 +23,19 @@ 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
// 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)
// 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