Add envprefix tag
This commit is contained in:
@@ -450,6 +450,7 @@ Tag | Description
|
|||||||
`group:"X"` | Logical group for a flag or command.
|
`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.
|
`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.
|
`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.
|
`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.
|
`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`.
|
`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.
|
// Accumulate prefixes.
|
||||||
subf.tag.Prefix = tag.Prefix + subf.tag.Prefix
|
subf.tag.Prefix = tag.Prefix + subf.tag.Prefix
|
||||||
|
subf.tag.EnvPrefix = tag.EnvPrefix + subf.tag.EnvPrefix
|
||||||
// Combine parent vars.
|
// Combine parent vars.
|
||||||
subf.tag.Vars = tag.Vars.CloneWith(subf.tag.Vars)
|
subf.tag.Vars = tag.Vars.CloneWith(subf.tag.Vars)
|
||||||
}
|
}
|
||||||
@@ -138,6 +139,8 @@ MAIN:
|
|||||||
name = tag.Prefix + name
|
name = tag.Prefix + name
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tag.Env = tag.EnvPrefix + tag.Env
|
||||||
|
|
||||||
// Nested structs are either commands or args, unless they implement the Mapper interface.
|
// 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 {
|
if field.value.Kind() == reflect.Struct && (tag.Cmd || tag.Arg) && k.registry.ForValue(fv) == nil {
|
||||||
typ := CommandNode
|
typ := CommandNode
|
||||||
|
|||||||
@@ -461,6 +461,20 @@ func TestEnvarAutoHelp(t *testing.T) {
|
|||||||
require.Contains(t, w.String(), "A flag ($FLAG).")
|
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) {
|
func TestCustomHelpFormatter(t *testing.T) {
|
||||||
var cli struct {
|
var cli struct {
|
||||||
Flag string `env:"FLAG" help:"A flag."`
|
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)
|
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) {
|
func TestEnvarsWithDefault(t *testing.T) {
|
||||||
var cli struct {
|
var cli struct {
|
||||||
Flag string `env:"KONG_FLAG" default:"default"`
|
Flag string `env:"KONG_FLAG" default:"default"`
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ type Tag struct {
|
|||||||
Xor []string
|
Xor []string
|
||||||
Vars Vars
|
Vars Vars
|
||||||
Prefix string // Optional prefix on anonymous structs. All sub-flags will have this prefix.
|
Prefix string // Optional prefix on anonymous structs. All sub-flags will have this prefix.
|
||||||
|
EnvPrefix string
|
||||||
Embed bool
|
Embed bool
|
||||||
Aliases []string
|
Aliases []string
|
||||||
Negatable bool
|
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.Xor = append(t.Xor, strings.FieldsFunc(xor, tagSplitFn)...)
|
||||||
}
|
}
|
||||||
t.Prefix = t.Get("prefix")
|
t.Prefix = t.Get("prefix")
|
||||||
|
t.EnvPrefix = t.Get("envprefix")
|
||||||
t.Embed = t.Has("embed")
|
t.Embed = t.Has("embed")
|
||||||
negatable := t.Has("negatable")
|
negatable := t.Has("negatable")
|
||||||
if negatable && !isBool {
|
if negatable && !isBool {
|
||||||
|
|||||||
Reference in New Issue
Block a user