Convert env management to a resolver.

This ensures that hooks correctly detect when values are set via
environment variables. Fixes #73.
This commit is contained in:
Alec Thomas
2020-04-16 22:19:21 +10:00
parent a77a484f6a
commit fbe8d48e4b
4 changed files with 35 additions and 11 deletions
+21
View File
@@ -0,0 +1,21 @@
package kong
import (
"os"
)
// EnvarResolver resolves values from environment variables.
//
// It is installed by default. Use ClearResolvers() to disable this.
func EnvarResolver() Resolver {
return ResolverFunc(func(context *Context, parent *Path, flag *Flag) (interface{}, error) {
if flag.Tag.Env == "" {
return nil, nil
}
envar := os.Getenv(flag.Tag.Env)
if envar != "" {
return envar, nil
}
return nil, nil
})
}
+1
View File
@@ -71,6 +71,7 @@ func New(grammar interface{}, options ...Option) (*Kong, error) {
vars: Vars{},
bindings: bindings{},
helpFormatter: DefaultHelpValueFormatter,
resolvers: []Resolver{EnvarResolver()},
}
options = append(options, Bind(k))
+13
View File
@@ -675,6 +675,19 @@ func TestHooksCalledForDefault(t *testing.T) {
require.Equal(t, []string{"before:default", "after:default"}, ctx.values)
}
func TestHooksCalledForEnv(t *testing.T) {
var cli struct {
Flag hookValue `env:"FLAG"`
}
defer tempEnv(envMap{"FLAG": "flagged"})()
ctx := &hookContext{}
_, err := mustNew(t, &cli, kong.Bind(ctx)).Parse(nil)
require.NoError(t, err)
require.Equal(t, "flagged", string(cli.Flag))
require.Equal(t, []string{"before:", "after:flagged"}, ctx.values)
}
func TestEnum(t *testing.T) {
var cli struct {
Flag string `enum:"a,b,c"`
-11
View File
@@ -3,7 +3,6 @@ package kong
import (
"fmt"
"math"
"os"
"reflect"
"strconv"
"strings"
@@ -326,16 +325,6 @@ func (v *Value) ApplyDefault() error {
// Does not include resolvers.
func (v *Value) Reset() error {
v.Target.Set(reflect.Zero(v.Target.Type()))
if v.Tag.Env != "" {
envar := os.Getenv(v.Tag.Env)
if envar != "" {
err := v.Parse(ScanFromTokens(Token{Type: FlagValueToken, Value: envar}), v.Target)
if err != nil {
return fmt.Errorf("%s (from envar %s=%q)", err, v.Tag.Env, envar)
}
return nil
}
}
if v.Default != "" {
return v.Parse(ScanFromTokens(Token{Type: FlagValueToken, Value: v.Default}), v.Target)
}