DefaultEnvars option (#177)

This commit is contained in:
Evgeny
2021-06-20 17:27:56 +07:00
committed by GitHub
parent 2d879d2037
commit a8244400e3
2 changed files with 109 additions and 2 deletions
+53
View File
@@ -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
View File
@@ -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