summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--example_test.go32
-rw-r--r--parse.go2
-rw-r--r--usage.go21
-rw-r--r--usage_test.go29
4 files changed, 79 insertions, 5 deletions
diff --git a/example_test.go b/example_test.go
index acfacad..6216e18 100644
--- a/example_test.go
+++ b/example_test.go
@@ -499,12 +499,12 @@ func Example_allSupportedTypes() {
func Example_envVarOnly() {
os.Args = split("./example")
- _ = os.Setenv("NUM_WORKERS", "my_key")
+ _ = os.Setenv("AUTH_KEY", "my_key")
- defer os.Unsetenv("NUM_WORKERS")
+ defer os.Unsetenv("AUTH_KEY")
var args struct {
- AuthKey string `arg:"-,--,env:NUM_WORKERS"`
+ AuthKey string `arg:"-,--,env:AUTH_KEY"`
}
MustParse(&args)
@@ -512,3 +512,29 @@ func Example_envVarOnly() {
fmt.Println(args.AuthKey)
// output: my_key
}
+
+func Example_envVarOnlyShouldIgnoreFlag() {
+ os.Args = split("./example --=my_key")
+
+ var args struct {
+ AuthKey string `arg:"-,--,env:AUTH_KEY"`
+ }
+
+ err := Parse(&args)
+
+ fmt.Println(err)
+ // output: unknown argument --=my_key
+}
+
+func Example_envVarOnlyShouldIgnoreShortFlag() {
+ os.Args = split("./example -=my_key")
+
+ var args struct {
+ AuthKey string `arg:"-,--,env:AUTH_KEY"`
+ }
+
+ err := Parse(&args)
+
+ fmt.Println(err)
+ // output: unknown argument -=my_key
+}
diff --git a/parse.go b/parse.go
index e5df067..aee60e7 100644
--- a/parse.go
+++ b/parse.go
@@ -656,7 +656,7 @@ func (p *Parser) process(args []string) error {
// lookup the spec for this option (note that the "specs" slice changes as
// we expand subcommands so it is better not to use a map)
spec := findOption(specs, opt)
- if spec == nil {
+ if spec == nil || opt == "" {
return fmt.Errorf("unknown argument %s", arg)
}
wasPresent[spec] = true
diff --git a/usage.go b/usage.go
index 43d6231..f032149 100644
--- a/usage.go
+++ b/usage.go
@@ -84,6 +84,11 @@ func (p *Parser) writeUsageForSubcommand(w io.Writer, cmd *command) {
ancestors = append(ancestors, ancestor.name)
ancestor = ancestor.parent
}
+ for _, spec := range cmd.specs {
+ if spec.short == "" && spec.long == "" {
+ ancestors = append(ancestors, spec.env+"="+strings.ToLower(spec.env)+"_value")
+ }
+ }
// print the beginning of the usage string
fmt.Fprint(w, "Usage:")
@@ -208,7 +213,7 @@ func (p *Parser) WriteHelpForSubcommand(w io.Writer, subcommand ...string) error
// writeHelp writes the usage string for the given subcommand
func (p *Parser) writeHelpForSubcommand(w io.Writer, cmd *command) {
- var positionals, longOptions, shortOptions []*spec
+ var positionals, longOptions, shortOptions, envOnlyOptions []*spec
for _, spec := range cmd.specs {
switch {
case spec.positional:
@@ -217,6 +222,8 @@ func (p *Parser) writeHelpForSubcommand(w io.Writer, cmd *command) {
longOptions = append(longOptions, spec)
case spec.short != "":
shortOptions = append(shortOptions, spec)
+ case spec.short == "" && spec.long == "":
+ envOnlyOptions = append(envOnlyOptions, spec)
}
}
@@ -275,6 +282,14 @@ func (p *Parser) writeHelpForSubcommand(w io.Writer, cmd *command) {
})
}
+ // write the list of environment only variables
+ if len(shortOptions)+len(longOptions) > 0 || cmd.parent == nil {
+ fmt.Fprint(w, "\nEnvironment variables:\n")
+ for _, spec := range envOnlyOptions {
+ p.printEnvOnlyVar(w, spec)
+ }
+ }
+
// write the list of subcommands
if len(cmd.subcommands) > 0 {
fmt.Fprint(w, "\nCommands:\n")
@@ -301,6 +316,10 @@ func (p *Parser) printOption(w io.Writer, spec *spec) {
}
}
+func (p *Parser) printEnvOnlyVar(w io.Writer, spec *spec) {
+ printTwoCols(w, spec.env, "", "", "")
+}
+
// lookupCommand finds a subcommand based on a sequence of subcommand names. The
// first string should be a top-level subcommand, the next should be a child
// subcommand of that subcommand, and so on. If no strings are given then the
diff --git a/usage_test.go b/usage_test.go
index 69feac2..d5e150f 100644
--- a/usage_test.go
+++ b/usage_test.go
@@ -646,3 +646,32 @@ Options:
p.WriteHelp(&help)
assert.Equal(t, expectedHelp[1:], help.String())
}
+
+func TestFailEnvOnly(t *testing.T) {
+ expectedUsage := "Usage: AUTH_KEY=auth_key_value example [--arg ARG]"
+
+ expectedHelp := `
+Usage: AUTH_KEY=auth_key_value example [--arg ARG]
+
+Options:
+ --arg ARG, -a ARG [env: MY_ARG]
+ --help, -h display this help and exit
+
+Environment variables:
+ AUTH_KEY
+`
+ var args struct {
+ ArgParam string `arg:"-a,--arg,env:MY_ARG"`
+ AuthKey string `arg:"-,--,env:AUTH_KEY"`
+ }
+ p, err := NewParser(Config{Program: "example"}, &args)
+ assert.NoError(t, err)
+
+ var help bytes.Buffer
+ p.WriteHelp(&help)
+ assert.Equal(t, expectedHelp[1:], help.String())
+
+ var usage bytes.Buffer
+ p.WriteUsage(&usage)
+ assert.Equal(t, expectedUsage, strings.TrimSpace(usage.String()))
+}