diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json index 069031488..68a75381d 100644 --- a/Godeps/Godeps.json +++ b/Godeps/Godeps.json @@ -24,8 +24,8 @@ }, { "ImportPath": "github.com/urfave/cli", - "Comment": "v1.17.0-57-gedb24d0", - "Rev": "edb24d02aa3cea2319c33f2836d4a5133907fe4c" + "Comment": "v1.18.0", + "Rev": "1efa31f08b9333f1bd4882d61f9d668a70cd902e" } ] } diff --git a/Godeps/_workspace/src/github.com/urfave/cli/.gitignore b/Godeps/_workspace/src/github.com/urfave/cli/.gitignore index 782377890..faf70c4c2 100644 --- a/Godeps/_workspace/src/github.com/urfave/cli/.gitignore +++ b/Godeps/_workspace/src/github.com/urfave/cli/.gitignore @@ -1 +1,2 @@ *.coverprofile +node_modules/ diff --git a/Godeps/_workspace/src/github.com/urfave/cli/.travis.yml b/Godeps/_workspace/src/github.com/urfave/cli/.travis.yml index 657e96a9d..273d017b4 100644 --- a/Godeps/_workspace/src/github.com/urfave/cli/.travis.yml +++ b/Godeps/_workspace/src/github.com/urfave/cli/.travis.yml @@ -2,6 +2,10 @@ language: go sudo: false +cache: + directories: + - node_modules + go: - 1.2.2 - 1.3.3 @@ -25,8 +29,12 @@ matrix: before_script: - go get github.com/urfave/gfmxr/... +- if [ ! -f node_modules/.bin/markdown-toc ] ; then + npm install markdown-toc ; + fi script: - ./runtests vet - ./runtests test - ./runtests gfmxr +- ./runtests toc diff --git a/Godeps/_workspace/src/github.com/urfave/cli/CHANGELOG.md b/Godeps/_workspace/src/github.com/urfave/cli/CHANGELOG.md index ac6d73a78..d1904fe0b 100644 --- a/Godeps/_workspace/src/github.com/urfave/cli/CHANGELOG.md +++ b/Godeps/_workspace/src/github.com/urfave/cli/CHANGELOG.md @@ -3,10 +3,13 @@ **ATTN**: This project uses [semantic versioning](http://semver.org/). ## [Unreleased] + +## [1.18.0] - 2016-06-27 ### Added - `./runtests` test runner with coverage tracking by default - testing on OS X - testing on Windows +- `UintFlag`, `Uint64Flag`, and `Int64Flag` types and supporting code ### Changed - Use spaces for alignment in help/usage output instead of tabs, making the @@ -14,6 +17,10 @@ ### Fixed - Printing of command aliases in help text +- Printing of visible flags for both struct and struct pointer flags +- Display the `help` subcommand when using `CommandCategories` +- No longer swallows `panic`s that occur within the `Action`s themselves when + detecting the signature of the `Action` field ## [1.17.0] - 2016-05-09 ### Added @@ -294,7 +301,8 @@ signature of `func(*cli.Context) error`, as defined by `cli.ActionFunc`. ### Added - Initial implementation. -[Unreleased]: https://github.com/urfave/cli/compare/v1.17.0...HEAD +[Unreleased]: https://github.com/urfave/cli/compare/v1.18.0...HEAD +[1.18.0]: https://github.com/urfave/cli/compare/v1.17.0...v1.18.0 [1.17.0]: https://github.com/urfave/cli/compare/v1.16.0...v1.17.0 [1.16.0]: https://github.com/urfave/cli/compare/v1.15.0...v1.16.0 [1.15.0]: https://github.com/urfave/cli/compare/v1.14.0...v1.15.0 diff --git a/Godeps/_workspace/src/github.com/urfave/cli/LICENSE b/Godeps/_workspace/src/github.com/urfave/cli/LICENSE index 5515ccfb7..42a597e29 100644 --- a/Godeps/_workspace/src/github.com/urfave/cli/LICENSE +++ b/Godeps/_workspace/src/github.com/urfave/cli/LICENSE @@ -1,21 +1,21 @@ -Copyright (C) 2013 Jeremy Saenz -All Rights Reserved. +MIT License -MIT LICENSE +Copyright (c) 2016 Jeremy Saenz & Contributors -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Godeps/_workspace/src/github.com/urfave/cli/README.md b/Godeps/_workspace/src/github.com/urfave/cli/README.md index 9bbfe836f..ebb1d7413 100644 --- a/Godeps/_workspace/src/github.com/urfave/cli/README.md +++ b/Godeps/_workspace/src/github.com/urfave/cli/README.md @@ -1,3 +1,6 @@ +cli +=== + [![Build Status](https://travis-ci.org/urfave/cli.svg?branch=master)](https://travis-ci.org/urfave/cli) [![Windows Build Status](https://ci.appveyor.com/api/projects/status/rtgk5xufi932pb2v?svg=true)](https://ci.appveyor.com/project/urfave/cli) [![GoDoc](https://godoc.org/github.com/urfave/cli?status.svg)](https://godoc.org/github.com/urfave/cli) @@ -6,9 +9,6 @@ [![top level coverage](https://gocover.io/_badge/github.com/urfave/cli?0 "top level coverage")](http://gocover.io/github.com/urfave/cli) / [![altsrc coverage](https://gocover.io/_badge/github.com/urfave/cli/altsrc?0 "altsrc coverage")](http://gocover.io/github.com/urfave/cli/altsrc) - -# cli - **Notice:** This is the library formerly known as `github.com/codegangsta/cli` -- Github will automatically redirect requests to this repository, but we recommend updating your references for clarity. @@ -17,6 +17,37 @@ cli is a simple, fast, and fun package for building command line apps in Go. The goal is to enable developers to write fast and distributable command line applications in an expressive way. + + +- [Overview](#overview) +- [Installation](#installation) + * [Supported platforms](#supported-platforms) + * [Using the `v2` branch](#using-the-v2-branch) + * [Pinning to the `v1` branch](#pinning-to-the-v1-branch) +- [Getting Started](#getting-started) +- [Examples](#examples) + * [Arguments](#arguments) + * [Flags](#flags) + + [Placeholder Values](#placeholder-values) + + [Alternate Names](#alternate-names) + + [Values from the Environment](#values-from-the-environment) + + [Values from alternate input sources (YAML and others)](#values-from-alternate-input-sources-yaml-and-others) + * [Subcommands](#subcommands) + * [Subcommands categories](#subcommands-categories) + * [Exit code](#exit-code) + * [Bash Completion](#bash-completion) + + [Enabling](#enabling) + + [Distribution](#distribution) + + [Customization](#customization) + * [Generated Help Text](#generated-help-text) + + [Customization](#customization-1) + * [Version Flag](#version-flag) + + [Customization](#customization-2) + + [Full API Example](#full-api-example) +- [Contribution Guidelines](#contribution-guidelines) + + + ## Overview Command line apps are usually so tiny that there is absolutely no reason why @@ -53,6 +84,8 @@ released version of Go on OS X and Windows. For full details, see ### Using the `v2` branch +**Warning**: The `v2` branch is currently unreleased and considered unstable. + There is currently a long-lived branch named `v2` that is intended to land as the new `master` branch once development there has settled down. The current `master` branch (mirrored as `v1`) is being manually merged into `v2` on @@ -211,7 +244,7 @@ COMMANDS: help, h Shows a list of commands or help for one command GLOBAL OPTIONS - --version Shows version information + --version Shows version information ``` ### Arguments @@ -980,11 +1013,11 @@ func main() { #### Full API Example -**NOTE**: This is a contrived (functioning) example meant strictly for API +**Notice**: This is a contrived (functioning) example meant strictly for API demonstration purposes. Use of one's imagination is encouraged. ``` go package main @@ -1036,6 +1069,19 @@ func (w *hexWriter) Write(p []byte) (int, error) { return len(p), nil } +type genericType struct{ + s string +} + +func (g *genericType) Set(value string) error { + g.s = value + return nil +} + +func (g *genericType) String() string { + return g.s +} + func main() { app := cli.NewApp() app.Name = "kənˈtrīv" @@ -1105,7 +1151,17 @@ func main() { app.Flags = []cli.Flag{ cli.BoolFlag{Name: "fancy"}, cli.BoolTFlag{Name: "fancier"}, + cli.DurationFlag{Name: "howlong, H", Value: time.Second * 3}, + cli.Float64Flag{Name: "howmuch"}, + cli.GenericFlag{Name: "wat", Value: &genericType{}}, + cli.Int64Flag{Name: "longdistance"}, + cli.Int64SliceFlag{Name: "intervals"}, + cli.IntFlag{Name: "distance"}, + cli.IntSliceFlag{Name: "times"}, cli.StringFlag{Name: "dance-move, d"}, + cli.StringSliceFlag{Name: "names, N"}, + cli.UintFlag{Name: "age"}, + cli.Uint64Flag{Name: "bigage"}, } app.EnableBashCompletion = true app.HideHelp = false @@ -1182,10 +1238,14 @@ func main() { fmt.Printf("%#v\n", nc.Duration("howlong")) fmt.Printf("%#v\n", nc.Float64("hay")) fmt.Printf("%#v\n", nc.Generic("bloop")) + fmt.Printf("%#v\n", nc.Int64("bonk")) + fmt.Printf("%#v\n", nc.Int64Slice("burnks")) fmt.Printf("%#v\n", nc.Int("bips")) fmt.Printf("%#v\n", nc.IntSlice("blups")) fmt.Printf("%#v\n", nc.String("snurt")) fmt.Printf("%#v\n", nc.StringSlice("snurkles")) + fmt.Printf("%#v\n", nc.Uint("flub")) + fmt.Printf("%#v\n", nc.Uint64("florb")) fmt.Printf("%#v\n", nc.GlobalBool("global-nope")) fmt.Printf("%#v\n", nc.GlobalBoolT("global-nerp")) fmt.Printf("%#v\n", nc.GlobalDuration("global-howlong")) diff --git a/Godeps/_workspace/src/github.com/urfave/cli/app.go b/Godeps/_workspace/src/github.com/urfave/cli/app.go index 9c7f679cb..a046c0128 100644 --- a/Godeps/_workspace/src/github.com/urfave/cli/app.go +++ b/Godeps/_workspace/src/github.com/urfave/cli/app.go @@ -8,6 +8,7 @@ import ( "path/filepath" "reflect" "sort" + "strings" "time" ) @@ -139,13 +140,6 @@ func (a *App) Setup() { } 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 { a.Commands = append(a.Commands, helpCommand) if (HelpFlag != BoolFlag{}) { @@ -153,7 +147,6 @@ func (a *App) Setup() { } } - //append version/help flags if a.EnableBashCompletion { a.appendFlag(BashCompletionFlag) } @@ -161,6 +154,12 @@ func (a *App) Setup() { if !a.HideVersion { a.appendFlag(VersionFlag) } + + a.categories = CommandCategories{} + for _, command := range a.Commands { + a.categories = a.categories.AddCommand(command.Category, command) + } + sort.Sort(a.categories) } // Run is the entry point to the cli app. Parses the arguments slice and routes @@ -464,11 +463,13 @@ func (a Author) String() string { func HandleAction(action interface{}, context *Context) (err error) { defer func() { if r := recover(); r != nil { - switch r.(type) { - case error: - err = r.(error) - default: - err = NewExitError(fmt.Sprintf("ERROR unknown Action error: %v. See %s", r, appActionDeprecationURL), 2) + // Try to detect a known reflection error from *this scope*, rather than + // swallowing all panics that may happen when calling an Action func. + s := fmt.Sprintf("%v", r) + if strings.HasPrefix(s, "reflect: ") && strings.Contains(s, "too many input arguments") { + err = NewExitError(fmt.Sprintf("ERROR unknown Action error: %v. See %s", r, appActionDeprecationURL), 2) + } else { + panic(r) } } }() diff --git a/Godeps/_workspace/src/github.com/urfave/cli/context.go b/Godeps/_workspace/src/github.com/urfave/cli/context.go index c34246369..879bae5ec 100644 --- a/Godeps/_workspace/src/github.com/urfave/cli/context.go +++ b/Godeps/_workspace/src/github.com/urfave/cli/context.go @@ -31,6 +31,21 @@ func (c *Context) Int(name string) int { return lookupInt(name, c.flagSet) } +// Int64 looks up the value of a local int flag, returns 0 if no int flag exists +func (c *Context) Int64(name string) int64 { + return lookupInt64(name, c.flagSet) +} + +// Uint looks up the value of a local int flag, returns 0 if no int flag exists +func (c *Context) Uint(name string) uint { + return lookupUint(name, c.flagSet) +} + +// Uint64 looks up the value of a local int flag, returns 0 if no int flag exists +func (c *Context) Uint64(name string) uint64 { + return lookupUint64(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 { @@ -70,6 +85,12 @@ func (c *Context) IntSlice(name string) []int { return lookupIntSlice(name, c.flagSet) } +// Int64Slice looks up the value of a local int slice flag, returns nil if no int +// slice flag exists +func (c *Context) Int64Slice(name string) []int64 { + return lookupInt64Slice(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{} { @@ -84,6 +105,30 @@ func (c *Context) GlobalInt(name string) int { return 0 } +// GlobalInt64 looks up the value of a global int flag, returns 0 if no int flag exists +func (c *Context) GlobalInt64(name string) int64 { + if fs := lookupGlobalFlagSet(name, c); fs != nil { + return lookupInt64(name, fs) + } + return 0 +} + +// GlobalUint looks up the value of a global int flag, returns 0 if no int flag exists +func (c *Context) GlobalUint(name string) uint { + if fs := lookupGlobalFlagSet(name, c); fs != nil { + return lookupUint(name, fs) + } + return 0 +} + +// GlobalUint64 looks up the value of a global int flag, returns 0 if no int flag exists +func (c *Context) GlobalUint64(name string) uint64 { + if fs := lookupGlobalFlagSet(name, c); fs != nil { + return lookupUint64(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 { @@ -147,6 +192,15 @@ func (c *Context) GlobalIntSlice(name string) []int { return nil } +// GlobalInt64Slice looks up the value of a global int slice flag, returns nil if +// no int slice flag exists +func (c *Context) GlobalInt64Slice(name string) []int64 { + if fs := lookupGlobalFlagSet(name, c); fs != nil { + return lookupInt64Slice(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{} { @@ -306,7 +360,46 @@ func lookupGlobalFlagSet(name string, ctx *Context) *flag.FlagSet { func lookupInt(name string, set *flag.FlagSet) int { f := set.Lookup(name) if f != nil { - val, err := strconv.Atoi(f.Value.String()) + val, err := strconv.ParseInt(f.Value.String(), 0, 64) + if err != nil { + return 0 + } + return int(val) + } + + return 0 +} + +func lookupInt64(name string, set *flag.FlagSet) int64 { + f := set.Lookup(name) + if f != nil { + val, err := strconv.ParseInt(f.Value.String(), 0, 64) + if err != nil { + return 0 + } + return val + } + + return 0 +} + +func lookupUint(name string, set *flag.FlagSet) uint { + f := set.Lookup(name) + if f != nil { + val, err := strconv.ParseUint(f.Value.String(), 0, 64) + if err != nil { + return 0 + } + return uint(val) + } + + return 0 +} + +func lookupUint64(name string, set *flag.FlagSet) uint64 { + f := set.Lookup(name) + if f != nil { + val, err := strconv.ParseUint(f.Value.String(), 0, 64) if err != nil { return 0 } @@ -370,6 +463,16 @@ func lookupIntSlice(name string, set *flag.FlagSet) []int { return nil } +func lookupInt64Slice(name string, set *flag.FlagSet) []int64 { + f := set.Lookup(name) + if f != nil { + return (f.Value.(*Int64Slice)).Value() + + } + + return nil +} + func lookupGeneric(name string, set *flag.FlagSet) interface{} { f := set.Lookup(name) if f != nil { diff --git a/Godeps/_workspace/src/github.com/urfave/cli/flag.go b/Godeps/_workspace/src/github.com/urfave/cli/flag.go index 1e8112e7e..f8a28d119 100644 --- a/Godeps/_workspace/src/github.com/urfave/cli/flag.go +++ b/Godeps/_workspace/src/github.com/urfave/cli/flag.go @@ -189,7 +189,7 @@ func (f *IntSlice) Set(value string) error { // String returns a readable representation of this value (for usage defaults) 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 @@ -245,6 +245,77 @@ func (f IntSliceFlag) GetName() string { return f.Name } +// Int64Slice is an opaque type for []int to satisfy flag.Value +type Int64Slice []int64 + +// Set parses the value into an integer and appends it to the list of values +func (f *Int64Slice) Set(value string) error { + tmp, err := strconv.ParseInt(value, 10, 64) + if err != nil { + return err + } + *f = append(*f, tmp) + return nil +} + +// String returns a readable representation of this value (for usage defaults) +func (f *Int64Slice) String() string { + return fmt.Sprintf("%#v", *f) +} + +// Value returns the slice of ints set by this flag +func (f *Int64Slice) Value() []int64 { + return *f +} + +// Int64SliceFlag is an int flag that can be specified multiple times on the +// command-line +type Int64SliceFlag struct { + Name string + Value *Int64Slice + Usage string + EnvVar string + Hidden bool +} + +// String returns the usage +func (f Int64SliceFlag) String() string { + return FlagStringer(f) +} + +// Apply populates the flag given the flag set and environment +func (f Int64SliceFlag) Apply(set *flag.FlagSet) { + if f.EnvVar != "" { + for _, envVar := range strings.Split(f.EnvVar, ",") { + envVar = strings.TrimSpace(envVar) + if envVal := os.Getenv(envVar); envVal != "" { + newVal := &Int64Slice{} + for _, s := range strings.Split(envVal, ",") { + s = strings.TrimSpace(s) + err := newVal.Set(s) + if err != nil { + fmt.Fprintf(ErrWriter, err.Error()) + } + } + f.Value = newVal + break + } + } + } + + eachName(f.Name, func(name string) { + if f.Value == nil { + f.Value = &Int64Slice{} + } + set.Var(f.Value, name, f.Usage) + }) +} + +// GetName returns the name of the flag. +func (f Int64SliceFlag) GetName() string { + return f.Name +} + // BoolFlag is a switch that defaults to false type BoolFlag struct { Name string @@ -376,7 +447,6 @@ func (f StringFlag) GetName() string { } // IntFlag is a flag that takes an integer -// Errors if the value provided cannot be parsed type IntFlag struct { Name string Value int @@ -420,6 +490,138 @@ func (f IntFlag) GetName() string { return f.Name } +// Int64Flag is a flag that takes a 64-bit integer +type Int64Flag struct { + Name string + Value int64 + Usage string + EnvVar string + Destination *int64 + Hidden bool +} + +// String returns the usage +func (f Int64Flag) String() string { + return FlagStringer(f) +} + +// Apply populates the flag given the flag set and environment +func (f Int64Flag) Apply(set *flag.FlagSet) { + if f.EnvVar != "" { + for _, envVar := range strings.Split(f.EnvVar, ",") { + envVar = strings.TrimSpace(envVar) + if envVal := os.Getenv(envVar); envVal != "" { + envValInt, err := strconv.ParseInt(envVal, 0, 64) + if err == nil { + f.Value = envValInt + 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) + }) +} + +// GetName returns the name of the flag. +func (f Int64Flag) GetName() string { + return f.Name +} + +// UintFlag is a flag that takes an unsigned integer +type UintFlag struct { + Name string + Value uint + Usage string + EnvVar string + Destination *uint + Hidden bool +} + +// String returns the usage +func (f UintFlag) String() string { + return FlagStringer(f) +} + +// Apply populates the flag given the flag set and environment +func (f UintFlag) Apply(set *flag.FlagSet) { + if f.EnvVar != "" { + for _, envVar := range strings.Split(f.EnvVar, ",") { + envVar = strings.TrimSpace(envVar) + if envVal := os.Getenv(envVar); envVal != "" { + envValInt, err := strconv.ParseUint(envVal, 0, 64) + if err == nil { + 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) + }) +} + +// GetName returns the name of the flag. +func (f UintFlag) GetName() string { + return f.Name +} + +// Uint64Flag is a flag that takes an unsigned 64-bit integer +type Uint64Flag struct { + Name string + Value uint64 + Usage string + EnvVar string + Destination *uint64 + Hidden bool +} + +// String returns the usage +func (f Uint64Flag) String() string { + return FlagStringer(f) +} + +// Apply populates the flag given the flag set and environment +func (f Uint64Flag) Apply(set *flag.FlagSet) { + if f.EnvVar != "" { + for _, envVar := range strings.Split(f.EnvVar, ",") { + envVar = strings.TrimSpace(envVar) + if envVal := os.Getenv(envVar); envVal != "" { + envValInt, err := strconv.ParseUint(envVal, 0, 64) + if err == nil { + 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) + }) +} + +// GetName returns the name of the flag. +func (f Uint64Flag) 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 { @@ -466,7 +668,6 @@ func (f DurationFlag) GetName() string { } // Float64Flag is a flag that takes an float value -// Errors if the value provided cannot be parsed type Float64Flag struct { Name string Value float64 @@ -512,7 +713,7 @@ func (f Float64Flag) GetName() string { func visibleFlags(fl []Flag) []Flag { visible := []Flag{} for _, flag := range fl { - if !reflect.ValueOf(flag).FieldByName("Hidden").Bool() { + if !flagValue(flag).FieldByName("Hidden").Bool() { visible = append(visible, flag) } } @@ -578,13 +779,24 @@ func withEnvHint(envVar, str string) string { return str + envText } -func stringifyFlag(f Flag) string { +func flagValue(f Flag) reflect.Value { 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) { case IntSliceFlag: return withEnvHint(fv.FieldByName("EnvVar").String(), stringifyIntSliceFlag(f.(IntSliceFlag))) + case Int64SliceFlag: + return withEnvHint(fv.FieldByName("EnvVar").String(), + stringifyInt64SliceFlag(f.(Int64SliceFlag))) case StringSliceFlag: return withEnvHint(fv.FieldByName("EnvVar").String(), stringifyStringSliceFlag(f.(StringSliceFlag))) @@ -630,6 +842,17 @@ func stringifyIntSliceFlag(f IntSliceFlag) string { 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 { defaultVals := []string{} if f.Value != nil && len(f.Value.Value()) > 0 { diff --git a/Godeps/_workspace/src/github.com/urfave/cli/help.go b/Godeps/_workspace/src/github.com/urfave/cli/help.go index f2ddc5499..0f4cf14cd 100644 --- a/Godeps/_workspace/src/github.com/urfave/cli/help.go +++ b/Godeps/_workspace/src/github.com/urfave/cli/help.go @@ -117,8 +117,9 @@ var HelpPrinter helpPrinter = printHelp var VersionPrinter = printVersion // ShowAppHelp is an action that displays the help. -func ShowAppHelp(c *Context) { +func ShowAppHelp(c *Context) error { HelpPrinter(c.App.Writer, AppHelpTemplate, c.App) + return nil } // DefaultAppComplete prints the list of subcommands as the default app completion method diff --git a/Godeps/_workspace/src/github.com/urfave/cli/runtests b/Godeps/_workspace/src/github.com/urfave/cli/runtests index 72c1f0ddf..0a7b483e3 100755 --- a/Godeps/_workspace/src/github.com/urfave/cli/runtests +++ b/Godeps/_workspace/src/github.com/urfave/cli/runtests @@ -18,7 +18,8 @@ def main(sysargs=sys.argv[:]): targets = { 'vet': _vet, 'test': _test, - 'gfmxr': _gfmxr + 'gfmxr': _gfmxr, + 'toc': _toc, } parser = argparse.ArgumentParser() @@ -62,6 +63,11 @@ def _vet(): _run('go vet ./...'.split()) +def _toc(): + _run(['node_modules/.bin/markdown-toc', '-i', 'README.md']) + _run(['git', 'diff', '--quiet']) + + def _run(command): print('runtests: {}'.format(' '.join(command)), file=sys.stderr) check_call(command)