Skip to content

Commit

Permalink
Fix default value display in help messages (#110)
Browse files Browse the repository at this point in the history
To display the default value as set by the developer, ignoring the later assignments (from env vars, user input, ...)

Fixes #98
  • Loading branch information
jawher authored Aug 8, 2020
1 parent 4f9d668 commit f62d725
Show file tree
Hide file tree
Showing 8 changed files with 131 additions and 15 deletions.
2 changes: 2 additions & 0 deletions args.go
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,8 @@ func (c *Cmd) mkArg(arg container.Container) {
panic(fmt.Sprintf("duplicate argument name %q", arg.Name))
}

arg.DefaultValue = values.DefaultValue(arg.Value)

arg.ValueSetFromEnv = values.SetFromEnv(arg.Value, arg.EnvVar)

c.args = append(c.args, &arg)
Expand Down
28 changes: 22 additions & 6 deletions cli_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -790,10 +790,14 @@ var genGolden = flag.Bool("g", false, "Generate golden file(s)")

func TestHelpMessage(t *testing.T) {
cases := []struct {
name string
params []string
name string
params []string
env map[string]string
exitCode int
}{
{name: "top-help", params: []string{"app", "-h"}},
{name: "top-help-i-user", params: []string{"app", "-i=5"}, exitCode: 2},
{name: "top-help-i-env", params: []string{"app"}, env: map[string]string{"INT1": "25"}, exitCode: 2},
{name: "command1", params: []string{"app", "command1", "-h"}},
{name: "command2", params: []string{"app", "command2", "-h"}},
{name: "command3", params: []string{"app", "command3", "-h"}},
Expand All @@ -807,9 +811,10 @@ func TestHelpMessage(t *testing.T) {
t.Logf("case: %+v", cas)
var out, stdErr string
defer captureAndRestoreOutput(&out, &stdErr)()
defer setAndRestoreEnv(cas.env)()

exitCalled := false
defer exitShouldBeCalledWith(t, 0, &exitCalled)()
defer exitShouldBeCalledWith(t, cas.exitCode, &exitCalled)()

app := App("app", "App Desc")
app.Spec = "[-bdsuikqs] [BOOL1 STR1 INT3...]"
Expand Down Expand Up @@ -856,8 +861,6 @@ func TestHelpMessage(t *testing.T) {
app.Ints(IntsArg{Name: "INTS2", Value: []int{1, 2, 3}, EnvVar: "INTS2", Desc: "Ints Argument 2"})
app.Ints(IntsArg{Name: "INTS3", Value: []int{1}, EnvVar: "INTS3", Desc: "Ints Argument 3", HideValue: true})

app.Action = func() {}

app.Command("command1", "command1 description", func(cmd *Cmd) {})
app.Command("command2", "command2 description", func(cmd *Cmd) {})
app.Command("command3", "command3 description", func(cmd *Cmd) {
Expand All @@ -879,7 +882,6 @@ func TestHelpMessage(t *testing.T) {

filename := fmt.Sprintf("testdata/help-output-%s.txt", cas.name)

fmt.Printf("golden file: %s\n", filename)
if *genGolden {
require.NoError(t,
ioutil.WriteFile(filename, []byte(stdErr), 0644))
Expand Down Expand Up @@ -2236,6 +2238,20 @@ func suppressOutput() func() {
return captureAndRestoreOutput(nil, nil)
}

func setAndRestoreEnv(env map[string]string) func() {
backup := map[string]string{}
for k, v := range env {
backup[k] = os.Getenv(k)
os.Setenv(k, v)
}

return func() {
for k, v := range backup {
os.Setenv(k, v)
}
}
}

func captureAndRestoreOutput(out, err *string) func() {
oldStdOut := stdOut
oldStdErr := stdErr
Expand Down
15 changes: 6 additions & 9 deletions commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import (
"github.com/jawher/mow.cli/internal/fsm"
"github.com/jawher/mow.cli/internal/lexer"
"github.com/jawher/mow.cli/internal/parser"
"github.com/jawher/mow.cli/internal/values"
)

/*
Expand Down Expand Up @@ -546,7 +545,7 @@ func (c *Cmd) printHelp(longDesc bool) {
for _, arg := range c.args {
var (
env = formatEnvVarsForHelp(arg.EnvVar)
value = formatValueForHelp(arg.HideValue, arg.Value)
value = formatValueForHelp(arg.HideValue, arg.DefaultValue)
)
printTabbedRow(w, arg.Name, joinStrings(arg.Desc, env, value))
}
Expand All @@ -559,7 +558,7 @@ func (c *Cmd) printHelp(longDesc bool) {
var (
optNames = formatOptNamesForHelp(opt)
env = formatEnvVarsForHelp(opt.EnvVar)
value = formatValueForHelp(opt.HideValue, opt.Value)
value = formatValueForHelp(opt.HideValue, opt.DefaultValue)
)
printTabbedRow(w, optNames, joinStrings(opt.Desc, env, value))
}
Expand Down Expand Up @@ -619,18 +618,16 @@ func formatOptNamesForHelp(o *container.Container) string {
}
}

func formatValueForHelp(hide bool, v flag.Value) string {
func formatValueForHelp(hide bool, v string) string {
if hide {
return ""
}

if dv, ok := v.(values.DefaultValued); ok {
if dv.IsDefault() {
return ""
}
if v == "" {
return ""
}

return fmt.Sprintf("(default %s)", v.String())
return fmt.Sprintf("(default %s)", v)
}

func formatEnvVarsForHelp(envVars string) string {
Expand Down
1 change: 1 addition & 0 deletions internal/container/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,5 @@ type Container struct {
ValueSetFromEnv bool
ValueSetByUser *bool
Value flag.Value
DefaultValue string
}
9 changes: 9 additions & 0 deletions internal/values/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,12 @@ func setMultivalued(into MultiValued, values []string) error {

return nil
}

func DefaultValue(v flag.Value) string {
if dv, ok := v.(DefaultValued); ok {
if dv.IsDefault() {
return ""
}
}
return v.String()
}
1 change: 1 addition & 0 deletions options.go
Original file line number Diff line number Diff line change
Expand Up @@ -467,6 +467,7 @@ func mkOptStrs(optName string) []string {
}

func (c *Cmd) mkOpt(opt container.Container) {
opt.DefaultValue = values.DefaultValue(opt.Value)
opt.ValueSetFromEnv = values.SetFromEnv(opt.Value, opt.EnvVar)

opt.Names = mkOptStrs(opt.Name)
Expand Down
45 changes: 45 additions & 0 deletions testdata/help-output-top-help-i-env.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@

Usage: app [-bdsuikqs] [BOOL1 STR1 INT3...] COMMAND [arg...]

App Desc

Arguments:
BOOL1 Bool Argument 1 (env $BOOL1)
BOOL2 Bool Argument 2 (default true)
BOOL3 Bool Argument 3 (env $BOOL3)
STR1 String Argument 1 (env $STR1)
STR2 String Argument 2 (env $STR2) (default "a value")
STR3 String Argument 3 (env $STR3)
INT1 Int Argument 1 (env $INT1) (default 0)
INT2 Int Argument 2 (env $INT2) (default 1)
INT3 Int Argument 3 (env $INT3)
STRS1 Strings Argument 1 (env $STRS1)
STRS2 (env $STRS2) (default ["value1", "value2"])
STRS3 Strings Argument 3 (env $STRS3)
INTS1 Ints Argument 1 (env $INTS1)
INTS2 Ints Argument 2 (env $INTS2) (default [1, 2, 3])
INTS3 Ints Argument 3 (env $INTS3)

Options:
-b, --bool1 Bool Option 1 (env $BOOL1)
--bool2 Bool Option 2 (default true)
-d Bool Option 3 (env $BOOL3)
-s, --str1 String Option 1 (env $STR1)
--str2 String Option 2 (default "a value")
-v String Option 3 (env $STR3)
-i, --int1 (env $INT1, $ALIAS_INT1) (default 0)
--int2 Int Option 2 (env $INT2) (default 1)
-k Int Option 3 (env $INT3)
-x, --strs1 Strings Option 1 (env $STRS1)
--strs2 Strings Option 2 (env $STRS2) (default ["value1", "value2"])
-z Strings Option 3 (env $STRS3)
-q, --ints1 Ints Option 1 (env $INTS1)
--ints2 Ints Option 2 (env $INTS2) (default [1, 2, 3])
-j Ints Option 3 (env $INTS3)

Commands:
command1 command1 description
command2 command2 description
command3 command3 description

Run 'app COMMAND --help' for more information on a command.
45 changes: 45 additions & 0 deletions testdata/help-output-top-help-i-user.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@

Usage: app [-bdsuikqs] [BOOL1 STR1 INT3...] COMMAND [arg...]

App Desc

Arguments:
BOOL1 Bool Argument 1 (env $BOOL1)
BOOL2 Bool Argument 2 (default true)
BOOL3 Bool Argument 3 (env $BOOL3)
STR1 String Argument 1 (env $STR1)
STR2 String Argument 2 (env $STR2) (default "a value")
STR3 String Argument 3 (env $STR3)
INT1 Int Argument 1 (env $INT1) (default 0)
INT2 Int Argument 2 (env $INT2) (default 1)
INT3 Int Argument 3 (env $INT3)
STRS1 Strings Argument 1 (env $STRS1)
STRS2 (env $STRS2) (default ["value1", "value2"])
STRS3 Strings Argument 3 (env $STRS3)
INTS1 Ints Argument 1 (env $INTS1)
INTS2 Ints Argument 2 (env $INTS2) (default [1, 2, 3])
INTS3 Ints Argument 3 (env $INTS3)

Options:
-b, --bool1 Bool Option 1 (env $BOOL1)
--bool2 Bool Option 2 (default true)
-d Bool Option 3 (env $BOOL3)
-s, --str1 String Option 1 (env $STR1)
--str2 String Option 2 (default "a value")
-v String Option 3 (env $STR3)
-i, --int1 (env $INT1, $ALIAS_INT1) (default 0)
--int2 Int Option 2 (env $INT2) (default 1)
-k Int Option 3 (env $INT3)
-x, --strs1 Strings Option 1 (env $STRS1)
--strs2 Strings Option 2 (env $STRS2) (default ["value1", "value2"])
-z Strings Option 3 (env $STRS3)
-q, --ints1 Ints Option 1 (env $INTS1)
--ints2 Ints Option 2 (env $INTS2) (default [1, 2, 3])
-j Ints Option 3 (env $INTS3)

Commands:
command1 command1 description
command2 command2 description
command3 command3 description

Run 'app COMMAND --help' for more information on a command.

0 comments on commit f62d725

Please sign in to comment.