Treat envars as higher priority than resolvers.
This commit is contained in:
@@ -198,6 +198,9 @@ func (c *Context) FlagValue(flag *Flag) interface{} {
|
||||
return v.Interface()
|
||||
}
|
||||
}
|
||||
if flag.Target.IsValid() {
|
||||
return flag.Target.Interface()
|
||||
}
|
||||
return flag.DefaultValue.Interface()
|
||||
}
|
||||
|
||||
|
||||
@@ -63,13 +63,12 @@ type Kong struct {
|
||||
// See the README (https://github.com/alecthomas/kong) for usage instructions.
|
||||
func New(grammar interface{}, options ...Option) (*Kong, error) {
|
||||
k := &Kong{
|
||||
Exit: os.Exit,
|
||||
Stdout: os.Stdout,
|
||||
Stderr: os.Stderr,
|
||||
registry: NewRegistry().RegisterDefaults(),
|
||||
resolvers: []ResolverFunc{Envars()},
|
||||
vars: Vars{},
|
||||
bindings: bindings{},
|
||||
Exit: os.Exit,
|
||||
Stdout: os.Stdout,
|
||||
Stderr: os.Stderr,
|
||||
registry: NewRegistry().RegisterDefaults(),
|
||||
vars: Vars{},
|
||||
bindings: bindings{},
|
||||
}
|
||||
|
||||
options = append(options, Bind(k))
|
||||
@@ -169,11 +168,12 @@ func (k *Kong) extraFlags() []*Flag {
|
||||
value := reflect.ValueOf(&helpTarget).Elem()
|
||||
helpFlag := &Flag{
|
||||
Value: &Value{
|
||||
Name: "help",
|
||||
Help: "Show context-sensitive help.",
|
||||
Target: value,
|
||||
Tag: &Tag{},
|
||||
Mapper: k.registry.ForValue(value),
|
||||
Name: "help",
|
||||
Help: "Show context-sensitive help.",
|
||||
Target: value,
|
||||
Tag: &Tag{},
|
||||
Mapper: k.registry.ForValue(value),
|
||||
DefaultValue: reflect.ValueOf(false),
|
||||
},
|
||||
}
|
||||
helpFlag.Flag = helpFlag
|
||||
|
||||
@@ -2,6 +2,7 @@ package kong
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
@@ -282,11 +283,22 @@ func (v *Value) Apply(value reflect.Value) {
|
||||
v.Set = true
|
||||
}
|
||||
|
||||
// Reset this value to its default, either the zero value or the parsed result of its "default" tag.
|
||||
// Reset this value to its default, either the zero value or the parsed result of its envar,
|
||||
// or its "default" tag.
|
||||
//
|
||||
// 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(Scan(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(Scan(v.Default), v.Target)
|
||||
}
|
||||
|
||||
-14
@@ -4,7 +4,6 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
@@ -61,16 +60,3 @@ func jsonDecodeValue(sep rune, value interface{}) (string, error) {
|
||||
}
|
||||
return "", fmt.Errorf("unsupported JSON value %v (of type %T)", value, value)
|
||||
}
|
||||
|
||||
// Envars resolves flag values using the `env:"<name>"` tag. It ignores flags without this tag.
|
||||
//
|
||||
// This resolver is installed by default.
|
||||
func Envars() ResolverFunc {
|
||||
return func(context *Context, parent *Path, flag *Flag) (string, error) {
|
||||
if flag.Tag.Env == "" {
|
||||
return "", nil
|
||||
}
|
||||
v, _ := os.LookupEnv(flag.Tag.Env)
|
||||
return v, nil
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,31 +61,6 @@ func TestEnvarsFlagOverride(t *testing.T) {
|
||||
require.Equal(t, "hello", cli.Flag)
|
||||
}
|
||||
|
||||
func TestEnvarsOnlyPopulateUsedBranches(t *testing.T) {
|
||||
// nolint
|
||||
var cli struct {
|
||||
UnvisitedArg struct {
|
||||
UnvisitedArg string `arg`
|
||||
Int int `env:"KONG_INT"`
|
||||
} `arg`
|
||||
UnvisitedCmd struct {
|
||||
Int int `env:"KONG_INT"`
|
||||
} `cmd`
|
||||
Visited struct {
|
||||
Int int `env:"KONG_INT"`
|
||||
} `cmd`
|
||||
}
|
||||
parser, restoreEnv := newEnvParser(t, &cli, envMap{"KONG_INT": "512"})
|
||||
defer restoreEnv()
|
||||
|
||||
_, err := parser.Parse([]string{"visited"})
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, 512, cli.Visited.Int)
|
||||
require.Equal(t, 0, cli.UnvisitedArg.Int)
|
||||
require.Equal(t, 0, cli.UnvisitedCmd.Int)
|
||||
}
|
||||
|
||||
func TestEnvarsTag(t *testing.T) {
|
||||
var cli struct {
|
||||
Slice []int `env:"KONG_NUMBERS"`
|
||||
|
||||
Reference in New Issue
Block a user