DefaultEnvars option (#177)
This commit is contained in:
+53
@@ -371,3 +371,56 @@ func ExpandPath(path string) string {
|
||||
}
|
||||
return abspath
|
||||
}
|
||||
|
||||
func siftStrings(ss []string, filter func(s string) bool) []string {
|
||||
i := 0
|
||||
ss = append([]string(nil), ss...)
|
||||
for _, s := range ss {
|
||||
if filter(s) {
|
||||
ss[i] = s
|
||||
i++
|
||||
}
|
||||
}
|
||||
return ss[0:i]
|
||||
}
|
||||
|
||||
// DefaultEnvars option inits environment names for flags.
|
||||
// The name will not generate if tag "env" is "-".
|
||||
// Predefined environment variables are skipped.
|
||||
//
|
||||
// For example:
|
||||
// --some.value -> PREFIX_SOME_VALUE
|
||||
func DefaultEnvars(prefix string) Option {
|
||||
processFlag := func(flag *Flag) {
|
||||
switch env := flag.Env; {
|
||||
case flag.Name == "help":
|
||||
return
|
||||
case env == "-":
|
||||
flag.Env = ""
|
||||
return
|
||||
case env != "":
|
||||
return
|
||||
}
|
||||
replacer := strings.NewReplacer("-", "_", ".", "_")
|
||||
names := append([]string{prefix}, camelCase(replacer.Replace(flag.Name))...)
|
||||
names = siftStrings(names, func(s string) bool { return !(s == "_" || strings.TrimSpace(s) == "") })
|
||||
name := strings.ToUpper(strings.Join(names, "_"))
|
||||
flag.Env = name
|
||||
flag.Value.Tag.Env = name
|
||||
}
|
||||
|
||||
var processNode func(node *Node)
|
||||
processNode = func(node *Node) {
|
||||
for _, flag := range node.Flags {
|
||||
processFlag(flag)
|
||||
}
|
||||
for _, node := range node.Children {
|
||||
processNode(node)
|
||||
}
|
||||
}
|
||||
|
||||
return PostBuild(func(k *Kong) error {
|
||||
processNode(k.Model.Node)
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
+56
-2
@@ -26,10 +26,10 @@ func tempEnv(env envMap) func() {
|
||||
}
|
||||
}
|
||||
|
||||
func newEnvParser(t *testing.T, cli interface{}, env envMap) (*kong.Kong, func()) {
|
||||
func newEnvParser(t *testing.T, cli interface{}, env envMap, options ...kong.Option) (*kong.Kong, func()) {
|
||||
t.Helper()
|
||||
restoreEnv := tempEnv(env)
|
||||
parser := mustNew(t, cli)
|
||||
parser := mustNew(t, cli, options...)
|
||||
return parser, restoreEnv
|
||||
}
|
||||
|
||||
@@ -92,6 +92,60 @@ func TestEnvarsWithDefault(t *testing.T) {
|
||||
require.Equal(t, "moo", cli.Flag)
|
||||
}
|
||||
|
||||
func TestEnv(t *testing.T) {
|
||||
type Embed struct {
|
||||
Flag string
|
||||
}
|
||||
type Cli struct {
|
||||
One Embed `prefix:"one-" embed:""`
|
||||
Two Embed `prefix:"two." embed:""`
|
||||
Three Embed `prefix:"three_" embed:""`
|
||||
Four Embed `prefix:"four_" embed:""`
|
||||
Five bool
|
||||
Six bool `env:"-"`
|
||||
}
|
||||
|
||||
var cli Cli
|
||||
|
||||
expected := Cli{
|
||||
One: Embed{Flag: "one"},
|
||||
Two: Embed{Flag: "two"},
|
||||
Three: Embed{Flag: "three"},
|
||||
Four: Embed{Flag: "four"},
|
||||
Five: true,
|
||||
}
|
||||
|
||||
// With the prefix
|
||||
parser, unsetEnvs := newEnvParser(t, &cli, envMap{
|
||||
"KONG_ONE_FLAG": "one",
|
||||
"KONG_TWO_FLAG": "two",
|
||||
"KONG_THREE_FLAG": "three",
|
||||
"KONG_FOUR_FLAG": "four",
|
||||
"KONG_FIVE": "true",
|
||||
"KONG_SIX": "true",
|
||||
}, kong.DefaultEnvars("KONG"))
|
||||
defer unsetEnvs()
|
||||
|
||||
_, err := parser.Parse(nil)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, expected, cli)
|
||||
|
||||
// Without the prefix
|
||||
parser, unsetEnvs = newEnvParser(t, &cli, envMap{
|
||||
"ONE_FLAG": "one",
|
||||
"TWO_FLAG": "two",
|
||||
"THREE_FLAG": "three",
|
||||
"FOUR_FLAG": "four",
|
||||
"FIVE": "true",
|
||||
"SIX": "true",
|
||||
}, kong.DefaultEnvars(""))
|
||||
defer unsetEnvs()
|
||||
|
||||
_, err = parser.Parse(nil)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, expected, cli)
|
||||
}
|
||||
|
||||
func TestJSONBasic(t *testing.T) {
|
||||
var cli struct {
|
||||
String string
|
||||
|
||||
Reference in New Issue
Block a user