Revert "Load environment variables as a resolver (#480)"
This reverts commit 3cedc44821.
Fixes #497, #498
This commit is contained in:
@@ -91,7 +91,7 @@ func New(grammar any, options ...Option) (*Kong, error) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
options = append(options, Bind(k), Resolvers(EnvResolver()))
|
options = append(options, Bind(k))
|
||||||
|
|
||||||
for _, option := range options {
|
for _, option := range options {
|
||||||
if err := option.Apply(k); err != nil {
|
if err := option.Apply(k); err != nil {
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package kong
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
|
"os"
|
||||||
"reflect"
|
"reflect"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -376,6 +377,19 @@ func (v *Value) ApplyDefault() error {
|
|||||||
// Does not include resolvers.
|
// Does not include resolvers.
|
||||||
func (v *Value) Reset() error {
|
func (v *Value) Reset() error {
|
||||||
v.Target.Set(reflect.Zero(v.Target.Type()))
|
v.Target.Set(reflect.Zero(v.Target.Type()))
|
||||||
|
if len(v.Tag.Envs) != 0 {
|
||||||
|
for _, env := range v.Tag.Envs {
|
||||||
|
envar, ok := os.LookupEnv(env)
|
||||||
|
// Parse the first non-empty ENV in the list
|
||||||
|
if ok {
|
||||||
|
err := v.Parse(ScanFromTokens(Token{Type: FlagValueToken, Value: envar}), v.Target)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("%s (from envar %s=%q)", err, env, envar)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
if v.HasDefault {
|
if v.HasDefault {
|
||||||
return v.Parse(ScanFromTokens(Token{Type: FlagValueToken, Value: v.Default}), v.Target)
|
return v.Parse(ScanFromTokens(Token{Type: FlagValueToken, Value: v.Default}), v.Target)
|
||||||
}
|
}
|
||||||
|
|||||||
-68
@@ -2,9 +2,7 @@ package kong
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
|
||||||
"io"
|
"io"
|
||||||
"os"
|
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -68,69 +66,3 @@ func snakeCase(name string) string {
|
|||||||
name = strings.Join(strings.Split(strings.Title(name), "-"), "")
|
name = strings.Join(strings.Split(strings.Title(name), "-"), "")
|
||||||
return strings.ToLower(name[:1]) + name[1:]
|
return strings.ToLower(name[:1]) + name[1:]
|
||||||
}
|
}
|
||||||
|
|
||||||
// EnvResolver provides a resolver for environment variables tags
|
|
||||||
func EnvResolver() Resolver {
|
|
||||||
// Resolvers are typically only invoked for flags, as shown here:
|
|
||||||
// https://github.com/alecthomas/kong/blob/v1.6.0/context.go#L567
|
|
||||||
// However, environment variable annotations can also apply to arguments,
|
|
||||||
// as demonstrated in this test:
|
|
||||||
// https://github.com/alecthomas/kong/blob/v1.6.0/kong_test.go#L1226-L1244
|
|
||||||
// To handle this, we ensure that arguments are resolved as well.
|
|
||||||
// Since the resolution only needs to happen once, we use this boolean
|
|
||||||
// to track whether the resolution process has already been performed.
|
|
||||||
argsResolved := false
|
|
||||||
return ResolverFunc(func(context *Context, parent *Path, flag *Flag) (interface{}, error) {
|
|
||||||
if !argsResolved {
|
|
||||||
if err := resolveArgs(context.Path); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
// once resolved we do not want to run this anymore
|
|
||||||
argsResolved = true
|
|
||||||
}
|
|
||||||
for _, env := range flag.Tag.Envs {
|
|
||||||
envar, ok := os.LookupEnv(env)
|
|
||||||
// Parse the first non-empty ENV in the list
|
|
||||||
if ok {
|
|
||||||
return envar, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil, nil
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func resolveArgs(paths []*Path) error {
|
|
||||||
for _, path := range paths {
|
|
||||||
if path.Command == nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
for _, positional := range path.Command.Positional {
|
|
||||||
if positional.Tag == nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if err := visitValue(positional); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if path.Command.Argument != nil {
|
|
||||||
if err := visitValue(path.Command.Argument); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func visitValue(value *Value) error {
|
|
||||||
for _, env := range value.Tag.Envs {
|
|
||||||
envar, ok := os.LookupEnv(env)
|
|
||||||
if !ok {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
token := Token{Type: FlagValueToken, Value: envar}
|
|
||||||
if err := value.Parse(ScanFromTokens(token), value.Target); err != nil {
|
|
||||||
return fmt.Errorf("%s (from envar %s=%q)", err, env, envar)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user