Skip to content

Commit b398b91

Browse files
authored
Feature: Add support for multiple env (#41)
1 parent 90dcd10 commit b398b91

File tree

8 files changed

+1209
-1186
lines changed

8 files changed

+1209
-1186
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ And you can use your favorite flag or cli library!
5252
- [x] Required
5353
- [ ] Placeholders (by `name`)
5454
- [x] Deprecated and hidden options
55-
- [ ] Multiple ENV names
55+
- [x] Multiple ENV names
5656
- [x] Interface for user types.
5757
- [x] [Validation](https://godoc.org/github.com/urfave/sflags/validator/govalidator#New) (using [govalidator](https://github.com/asaskevich/govalidator) package)
5858
- [x] Anonymous nested structure support (anonymous structures flatten by default)

flag.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ package sflags
55
type Flag struct {
66
Name string // name as it appears on command line
77
Short string // optional short name
8-
EnvName string
8+
EnvNames []string
99
Usage string // help message
1010
Value Value // value as set
1111
DefValue string // default value (as text); for usage message

gen/gcli/gcli.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ func GenerateTo(src []*sflags.Flag, dst *[]cli.Flag) {
1616
}
1717
*dst = append(*dst, &cli.GenericFlag{
1818
Name: name,
19-
EnvVars: []string{srcFlag.EnvName},
19+
EnvVars: srcFlag.EnvNames,
2020
Aliases: aliases,
2121
Hidden: srcFlag.Hidden,
2222
Usage: srcFlag.Usage,

gen/gcli/gcliv3.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ func GenerateToV3(src []*sflags.Flag, dst *[]cli.Flag) {
4141
}
4242
*dst = append(*dst, &cli.GenericFlag{
4343
Name: name,
44-
Sources: cli.EnvVars(srcFlag.EnvName),
44+
Sources: cli.EnvVars(srcFlag.EnvNames...),
4545
Aliases: aliases,
4646
Hidden: srcFlag.Hidden,
4747
Usage: srcFlag.Usage,

gen/gkingpin/gkingpin.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ func GenerateTo(src []*sflags.Flag, dst flagger) {
1717
for _, srcFlag := range src {
1818
flag := dst.Flag(srcFlag.Name, srcFlag.Usage)
1919
flag.SetValue(srcFlag.Value)
20-
if srcFlag.EnvName != "" {
21-
flag.Envar(srcFlag.EnvName)
20+
if len(srcFlag.EnvNames) > 0 && srcFlag.EnvNames[0] != "" {
21+
flag.Envar(srcFlag.EnvNames[0])
2222
}
2323
if srcFlag.Hidden {
2424
flag.Hidden()

parser.go

Lines changed: 30 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -123,37 +123,47 @@ func parseFlagTag(field reflect.StructField, opt opts) *Flag {
123123
return &flag
124124
}
125125

126-
func parseEnv(flagName string, field reflect.StructField, opt opts) string {
127-
ignoreEnvPrefix := false
128-
envVar := flagToEnv(flagName, opt.flagDivider, opt.envDivider)
126+
func parseEnv(flagName string, field reflect.StructField, opt opts) []string {
127+
var envVars []string
128+
flagEnvVar := flagToEnv(flagName, opt.flagDivider, opt.envDivider)
129129
if envTags := strings.Split(field.Tag.Get(defaultEnvTag), ","); len(envTags) > 0 {
130130
switch envName := envTags[0]; envName {
131131
case "-":
132-
// if tag is `env:"-"` then won't fill flag from environment
133-
envVar = ""
132+
return envVars
134133
case "":
135134
// if tag is `env:""` then env var will be taken from flag name
135+
envVars = append(envVars, opt.envPrefix+flagEnvVar)
136136
default:
137137
// if tag is `env:"NAME"` then env var is envPrefix_flagPrefix_NAME
138138
// if tag is `env:"~NAME"` then env var is NAME
139-
if strings.HasPrefix(envName, "~") {
140-
envVar = envName[1:]
141-
ignoreEnvPrefix = true
142-
} else {
143-
envVar = envName
144-
if opt.prefix != "" {
145-
envVar = flagToEnv(
146-
opt.prefix,
147-
opt.flagDivider,
148-
opt.envDivider) + envVar
139+
for _, envName := range envTags {
140+
ignoreEnvPrefix := false
141+
var envVar string
142+
if strings.HasPrefix(envName, "~") {
143+
envVar = envName[1:]
144+
ignoreEnvPrefix = true
145+
} else {
146+
envVar = envName
147+
if opt.prefix != "" {
148+
envVar = flagToEnv(
149+
opt.prefix,
150+
opt.flagDivider,
151+
opt.envDivider) + envVar
152+
}
153+
}
154+
if envVar != "" {
155+
if !ignoreEnvPrefix {
156+
envVars = append(envVars, opt.envPrefix+envVar)
157+
} else {
158+
envVars = append(envVars, envVar)
159+
}
149160
}
150161
}
151162
}
163+
} else if flagEnvVar != "" {
164+
envVars = append(envVars, opt.envPrefix+flagEnvVar)
152165
}
153-
if envVar != "" && opt.envPrefix != "" && !ignoreEnvPrefix {
154-
envVar = opt.envPrefix + envVar
155-
}
156-
return envVar
166+
return envVars
157167
}
158168

159169
// ParseStruct parses structure and returns list of flags based on this structure.
@@ -247,7 +257,7 @@ fields:
247257
continue fields
248258
}
249259

250-
flag.EnvName = parseEnv(flag.Name, field, opt)
260+
flag.EnvNames = parseEnv(flag.Name, field, opt)
251261
flag.Usage = field.Tag.Get(opt.descTag)
252262
prefix := flag.Name + opt.flagDivider
253263
if field.Anonymous && opt.flatten {

0 commit comments

Comments
 (0)