Add envprefix tag

This commit is contained in:
Dan
2021-10-22 11:28:58 +07:00
committed by Alec Thomas
parent 749d3f0752
commit 2770a34ce6
5 changed files with 53 additions and 0 deletions
+1
View File
@@ -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`.
+3
View File
@@ -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
+14
View File
@@ -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."`
+33
View File
@@ -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"`
+2
View File
@@ -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 {