From 7747b4146b600a1e64fef08b58e5074843179f40 Mon Sep 17 00:00:00 2001 From: Alec Thomas Date: Thu, 13 Feb 2025 11:17:47 -0800 Subject: [PATCH] Revert "Load environment variables as a resolver (#480)" This reverts commit 3cedc448212efa54577c7d6c601b079a49b2c2da. Fixes #497, #498 --- kong.go | 2 +- model.go | 14 +++++++++++ resolver.go | 68 ----------------------------------------------------- 3 files changed, 15 insertions(+), 69 deletions(-) diff --git a/kong.go b/kong.go index 3cb2e40..b85e145 100644 --- a/kong.go +++ b/kong.go @@ -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 { if err := option.Apply(k); err != nil { diff --git a/model.go b/model.go index 3913239..065fcdd 100644 --- a/model.go +++ b/model.go @@ -3,6 +3,7 @@ package kong import ( "fmt" "math" + "os" "reflect" "strconv" "strings" @@ -376,6 +377,19 @@ func (v *Value) ApplyDefault() error { // Does not include resolvers. func (v *Value) Reset() error { 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 { return v.Parse(ScanFromTokens(Token{Type: FlagValueToken, Value: v.Default}), v.Target) } diff --git a/resolver.go b/resolver.go index d28158f..29be1b9 100644 --- a/resolver.go +++ b/resolver.go @@ -2,9 +2,7 @@ package kong import ( "encoding/json" - "fmt" "io" - "os" "strings" ) @@ -68,69 +66,3 @@ func snakeCase(name string) string { name = strings.Join(strings.Split(strings.Title(name), "-"), "") 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 -}