Add envprefix tag
This commit is contained in:
@@ -450,6 +450,7 @@ Tag | Description
|
||||
`group:"X"` | Logical group for a flag or command.
|
||||
`xor:"X,Y,..."` | Exclusive OR groups for flags. Only one flag in the group can be used which is restricted within the same command. When combined with `required`, at least one of the `xor` group will be required.
|
||||
`prefix:"X"` | Prefix for all sub-flags.
|
||||
`envprefix:"X"` | Envar prefix for all sub-flags.
|
||||
`set:"K=V"` | Set a variable for expansion by child elements. Multiples can occur.
|
||||
`embed:""` | If present, this field's children will be embedded in the parent. Useful for composition.
|
||||
`passthrough:""` | If present, this positional argument stops flag parsing when encountered, as if `--` was processed before. Useful for external command wrappers, like `exec`.
|
||||
|
||||
@@ -97,6 +97,7 @@ func flattenedFields(v reflect.Value) (out []flattenedField, err error) {
|
||||
}
|
||||
// Accumulate prefixes.
|
||||
subf.tag.Prefix = tag.Prefix + subf.tag.Prefix
|
||||
subf.tag.EnvPrefix = tag.EnvPrefix + subf.tag.EnvPrefix
|
||||
// Combine parent vars.
|
||||
subf.tag.Vars = tag.Vars.CloneWith(subf.tag.Vars)
|
||||
}
|
||||
@@ -138,6 +139,8 @@ MAIN:
|
||||
name = tag.Prefix + name
|
||||
}
|
||||
|
||||
tag.Env = tag.EnvPrefix + tag.Env
|
||||
|
||||
// Nested structs are either commands or args, unless they implement the Mapper interface.
|
||||
if field.value.Kind() == reflect.Struct && (tag.Cmd || tag.Arg) && k.registry.ForValue(fv) == nil {
|
||||
typ := CommandNode
|
||||
|
||||
@@ -461,6 +461,20 @@ func TestEnvarAutoHelp(t *testing.T) {
|
||||
require.Contains(t, w.String(), "A flag ($FLAG).")
|
||||
}
|
||||
|
||||
func TestEnvarAutoHelpWithEnvPrefix(t *testing.T) {
|
||||
type Anonymous struct {
|
||||
Flag string `env:"FLAG" help:"A flag."`
|
||||
}
|
||||
var cli struct {
|
||||
Anonymous `envprefix:"ANON_"`
|
||||
}
|
||||
w := &strings.Builder{}
|
||||
p := mustNew(t, &cli, kong.Writers(w, w), kong.Exit(func(int) {}))
|
||||
_, err := p.Parse([]string{"--help"})
|
||||
require.NoError(t, err)
|
||||
require.Contains(t, w.String(), "A flag ($ANON_FLAG).")
|
||||
}
|
||||
|
||||
func TestCustomHelpFormatter(t *testing.T) {
|
||||
var cli struct {
|
||||
Flag string `env:"FLAG" help:"A flag."`
|
||||
|
||||
@@ -74,6 +74,39 @@ func TestEnvarsTag(t *testing.T) {
|
||||
require.Equal(t, []int{5, 2, 9}, cli.Slice)
|
||||
}
|
||||
|
||||
func TestEnvarsEnvPrefix(t *testing.T) {
|
||||
type Anonymous struct {
|
||||
Slice []int `env:"NUMBERS"`
|
||||
}
|
||||
var cli struct {
|
||||
Anonymous `envprefix:"KONG_"`
|
||||
}
|
||||
parser, restoreEnv := newEnvParser(t, &cli, envMap{"KONG_NUMBERS": "1,2,3"})
|
||||
defer restoreEnv()
|
||||
|
||||
_, err := parser.Parse([]string{})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, []int{1, 2, 3}, cli.Slice)
|
||||
}
|
||||
|
||||
func TestEnvarsNestedEnvPrefix(t *testing.T) {
|
||||
type NestedAnonymous struct {
|
||||
String string `env:"STRING"`
|
||||
}
|
||||
type Anonymous struct {
|
||||
NestedAnonymous `envprefix:"ANON_"`
|
||||
}
|
||||
var cli struct {
|
||||
Anonymous `envprefix:"KONG_"`
|
||||
}
|
||||
parser, restoreEnv := newEnvParser(t, &cli, envMap{"KONG_ANON_STRING": "abc"})
|
||||
defer restoreEnv()
|
||||
|
||||
_, err := parser.Parse([]string{})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, "abc", cli.String)
|
||||
}
|
||||
|
||||
func TestEnvarsWithDefault(t *testing.T) {
|
||||
var cli struct {
|
||||
Flag string `env:"KONG_FLAG" default:"default"`
|
||||
|
||||
@@ -32,6 +32,7 @@ type Tag struct {
|
||||
Xor []string
|
||||
Vars Vars
|
||||
Prefix string // Optional prefix on anonymous structs. All sub-flags will have this prefix.
|
||||
EnvPrefix string
|
||||
Embed bool
|
||||
Aliases []string
|
||||
Negatable bool
|
||||
@@ -196,6 +197,7 @@ func hydrateTag(t *Tag, typeName string, isBool bool) error {
|
||||
t.Xor = append(t.Xor, strings.FieldsFunc(xor, tagSplitFn)...)
|
||||
}
|
||||
t.Prefix = t.Get("prefix")
|
||||
t.EnvPrefix = t.Get("envprefix")
|
||||
t.Embed = t.Has("embed")
|
||||
negatable := t.Has("negatable")
|
||||
if negatable && !isBool {
|
||||
|
||||
Reference in New Issue
Block a user