Merge pull request #514 from grubernaut/f-default-value-text
Add DefaultValue text for flags
This commit is contained in:
commit
c72728f424
43
README.md
43
README.md
@ -32,6 +32,7 @@ applications in an expressive way.
|
|||||||
+ [Alternate Names](#alternate-names)
|
+ [Alternate Names](#alternate-names)
|
||||||
+ [Values from the Environment](#values-from-the-environment)
|
+ [Values from the Environment](#values-from-the-environment)
|
||||||
+ [Values from alternate input sources (YAML, TOML, and others)](#values-from-alternate-input-sources-yaml-toml-and-others)
|
+ [Values from alternate input sources (YAML, TOML, and others)](#values-from-alternate-input-sources-yaml-toml-and-others)
|
||||||
|
+ [Default Values for help output](#default-values-for-help-output)
|
||||||
* [Subcommands](#subcommands)
|
* [Subcommands](#subcommands)
|
||||||
* [Subcommands categories](#subcommands-categories)
|
* [Subcommands categories](#subcommands-categories)
|
||||||
* [Exit code](#exit-code)
|
* [Exit code](#exit-code)
|
||||||
@ -589,6 +590,48 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### Default Values for help output
|
||||||
|
|
||||||
|
Sometimes it's useful to specify a flag's default help-text value within the flag declaration. This can be useful if the default value for a flag is a computed value. The default value can be set via the `DefaultText` struct field.
|
||||||
|
|
||||||
|
For example this:
|
||||||
|
|
||||||
|
<!-- {
|
||||||
|
"args": ["--help"],
|
||||||
|
"output": "--port value"
|
||||||
|
} -->
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"gopkg.in/urfave/cli.v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
app := &cli.App{
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
&cli.IntFlag{
|
||||||
|
Name: "port",
|
||||||
|
Usage: "Use a randomized port",
|
||||||
|
Value: 0,
|
||||||
|
DefaultText: "random",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
app.Run(os.Args)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Will result in help output like:
|
||||||
|
|
||||||
|
```
|
||||||
|
--port value Use a randomized port (default: random)
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
### Subcommands
|
### Subcommands
|
||||||
|
|
||||||
Subcommands can be defined for a more git-like command line app.
|
Subcommands can be defined for a more git-like command line app.
|
||||||
|
7
flag.go
7
flag.go
@ -730,7 +730,6 @@ func stringifyFlag(f Flag) string {
|
|||||||
needsPlaceholder := false
|
needsPlaceholder := false
|
||||||
defaultValueString := ""
|
defaultValueString := ""
|
||||||
val := fv.FieldByName("Value")
|
val := fv.FieldByName("Value")
|
||||||
|
|
||||||
if val.IsValid() {
|
if val.IsValid() {
|
||||||
needsPlaceholder = val.Kind() != reflect.Bool
|
needsPlaceholder = val.Kind() != reflect.Bool
|
||||||
defaultValueString = fmt.Sprintf(" (default: %v)", val.Interface())
|
defaultValueString = fmt.Sprintf(" (default: %v)", val.Interface())
|
||||||
@ -740,6 +739,12 @@ func stringifyFlag(f Flag) string {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
helpText := fv.FieldByName("DefaultText")
|
||||||
|
if helpText.IsValid() && helpText.String() != "" {
|
||||||
|
needsPlaceholder = val.Kind() != reflect.Bool
|
||||||
|
defaultValueString = fmt.Sprintf(" (default: %s)", helpText.String())
|
||||||
|
}
|
||||||
|
|
||||||
if defaultValueString == " (default: )" {
|
if defaultValueString == " (default: )" {
|
||||||
defaultValueString = ""
|
defaultValueString = ""
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@ type BoolFlag struct {
|
|||||||
EnvVars []string
|
EnvVars []string
|
||||||
Hidden bool
|
Hidden bool
|
||||||
Value bool
|
Value bool
|
||||||
|
DefaultText string
|
||||||
Destination *bool
|
Destination *bool
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,6 +60,7 @@ type DurationFlag struct {
|
|||||||
EnvVars []string
|
EnvVars []string
|
||||||
Hidden bool
|
Hidden bool
|
||||||
Value time.Duration
|
Value time.Duration
|
||||||
|
DefaultText string
|
||||||
Destination *time.Duration
|
Destination *time.Duration
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,6 +104,7 @@ type Float64Flag struct {
|
|||||||
EnvVars []string
|
EnvVars []string
|
||||||
Hidden bool
|
Hidden bool
|
||||||
Value float64
|
Value float64
|
||||||
|
DefaultText string
|
||||||
Destination *float64
|
Destination *float64
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -145,6 +148,7 @@ type GenericFlag struct {
|
|||||||
EnvVars []string
|
EnvVars []string
|
||||||
Hidden bool
|
Hidden bool
|
||||||
Value Generic
|
Value Generic
|
||||||
|
DefaultText string
|
||||||
}
|
}
|
||||||
|
|
||||||
// String returns a readable representation of this value
|
// String returns a readable representation of this value
|
||||||
@ -187,6 +191,7 @@ type Int64Flag struct {
|
|||||||
EnvVars []string
|
EnvVars []string
|
||||||
Hidden bool
|
Hidden bool
|
||||||
Value int64
|
Value int64
|
||||||
|
DefaultText string
|
||||||
Destination *int64
|
Destination *int64
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -230,6 +235,7 @@ type IntFlag struct {
|
|||||||
EnvVars []string
|
EnvVars []string
|
||||||
Hidden bool
|
Hidden bool
|
||||||
Value int
|
Value int
|
||||||
|
DefaultText string
|
||||||
Destination *int
|
Destination *int
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -273,6 +279,7 @@ type IntSliceFlag struct {
|
|||||||
EnvVars []string
|
EnvVars []string
|
||||||
Hidden bool
|
Hidden bool
|
||||||
Value *IntSlice
|
Value *IntSlice
|
||||||
|
DefaultText string
|
||||||
}
|
}
|
||||||
|
|
||||||
// String returns a readable representation of this value
|
// String returns a readable representation of this value
|
||||||
@ -315,6 +322,7 @@ type Int64SliceFlag struct {
|
|||||||
EnvVars []string
|
EnvVars []string
|
||||||
Hidden bool
|
Hidden bool
|
||||||
Value *Int64Slice
|
Value *Int64Slice
|
||||||
|
DefaultText string
|
||||||
}
|
}
|
||||||
|
|
||||||
// String returns a readable representation of this value
|
// String returns a readable representation of this value
|
||||||
@ -357,6 +365,7 @@ type Float64SliceFlag struct {
|
|||||||
EnvVars []string
|
EnvVars []string
|
||||||
Hidden bool
|
Hidden bool
|
||||||
Value *Float64Slice
|
Value *Float64Slice
|
||||||
|
DefaultText string
|
||||||
}
|
}
|
||||||
|
|
||||||
// String returns a readable representation of this value
|
// String returns a readable representation of this value
|
||||||
@ -399,6 +408,7 @@ type StringFlag struct {
|
|||||||
EnvVars []string
|
EnvVars []string
|
||||||
Hidden bool
|
Hidden bool
|
||||||
Value string
|
Value string
|
||||||
|
DefaultText string
|
||||||
Destination *string
|
Destination *string
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -442,6 +452,7 @@ type StringSliceFlag struct {
|
|||||||
EnvVars []string
|
EnvVars []string
|
||||||
Hidden bool
|
Hidden bool
|
||||||
Value *StringSlice
|
Value *StringSlice
|
||||||
|
DefaultText string
|
||||||
}
|
}
|
||||||
|
|
||||||
// String returns a readable representation of this value
|
// String returns a readable representation of this value
|
||||||
@ -484,6 +495,7 @@ type Uint64Flag struct {
|
|||||||
EnvVars []string
|
EnvVars []string
|
||||||
Hidden bool
|
Hidden bool
|
||||||
Value uint64
|
Value uint64
|
||||||
|
DefaultText string
|
||||||
Destination *uint64
|
Destination *uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -527,6 +539,7 @@ type UintFlag struct {
|
|||||||
EnvVars []string
|
EnvVars []string
|
||||||
Hidden bool
|
Hidden bool
|
||||||
Value uint
|
Value uint
|
||||||
|
DefaultText string
|
||||||
Destination *uint
|
Destination *uint
|
||||||
}
|
}
|
||||||
|
|
||||||
|
15
flag_test.go
15
flag_test.go
@ -67,6 +67,16 @@ func TestStringFlagHelpOutput(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestStringFlagDefaultText(t *testing.T) {
|
||||||
|
flag := &StringFlag{Name: "foo", Aliases: nil, Usage: "amount of `foo` requested", Value: "none", DefaultText: "all of it"}
|
||||||
|
expected := "--foo foo\tamount of foo requested (default: all of it)"
|
||||||
|
output := flag.String()
|
||||||
|
|
||||||
|
if output != expected {
|
||||||
|
t.Errorf("%q does not match %q", output, expected)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestStringFlagWithEnvVarHelpOutput(t *testing.T) {
|
func TestStringFlagWithEnvVarHelpOutput(t *testing.T) {
|
||||||
os.Clearenv()
|
os.Clearenv()
|
||||||
os.Setenv("APP_FOO", "derp")
|
os.Setenv("APP_FOO", "derp")
|
||||||
@ -482,7 +492,6 @@ func TestFloat64FlagApply_SetsAllNames(t *testing.T) {
|
|||||||
expect(t, v, float64(43.33333))
|
expect(t, v, float64(43.33333))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
var float64SliceFlagTests = []struct {
|
var float64SliceFlagTests = []struct {
|
||||||
name string
|
name string
|
||||||
aliases []string
|
aliases []string
|
||||||
@ -523,8 +532,6 @@ func TestFloat64SliceFlagWithEnvVarHelpOutput(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var genericFlagTests = []struct {
|
var genericFlagTests = []struct {
|
||||||
name string
|
name string
|
||||||
value Generic
|
value Generic
|
||||||
@ -1100,7 +1107,6 @@ func TestParseMultiFloat64FromEnvCascade(t *testing.T) {
|
|||||||
a.Run([]string{"run"})
|
a.Run([]string{"run"})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func TestParseMultiFloat64SliceFromEnv(t *testing.T) {
|
func TestParseMultiFloat64SliceFromEnv(t *testing.T) {
|
||||||
os.Clearenv()
|
os.Clearenv()
|
||||||
os.Setenv("APP_INTERVALS", "0.1,-10.5")
|
os.Setenv("APP_INTERVALS", "0.1,-10.5")
|
||||||
@ -1141,7 +1147,6 @@ func TestParseMultiFloat64SliceFromEnvCascade(t *testing.T) {
|
|||||||
}).Run([]string{"run"})
|
}).Run([]string{"run"})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func TestParseMultiBool(t *testing.T) {
|
func TestParseMultiBool(t *testing.T) {
|
||||||
a := App{
|
a := App{
|
||||||
Flags: []Flag{
|
Flags: []Flag{
|
||||||
|
@ -145,6 +145,7 @@ def _write_cli_flag_types(outfile, types):
|
|||||||
EnvVars []string
|
EnvVars []string
|
||||||
Hidden bool
|
Hidden bool
|
||||||
Value {type}
|
Value {type}
|
||||||
|
DefaultText string
|
||||||
""".format(**typedef))
|
""".format(**typedef))
|
||||||
|
|
||||||
if typedef['dest']:
|
if typedef['dest']:
|
||||||
|
Loading…
Reference in New Issue
Block a user