-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathenvflag.go
More file actions
72 lines (57 loc) · 1.74 KB
/
envflag.go
File metadata and controls
72 lines (57 loc) · 1.74 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
package envflag
import (
"flag"
"os"
"strings"
)
// Envflag is a environment-variable wrapper for flag.FlagSet.
type Envflag struct {
Cli *flag.FlagSet
}
// DefaultEnvflag is the default Envflag and is used by Parse.
var DefaultEnvflag = &Envflag{
Cli: flag.CommandLine,
}
// Parse parses the command-line flags from os.Args[1:].
// For unset flags, it will attempt to read & set from environment variables.
// Must be called after all flags are defined and before flags are accessed by the program.
func (e Envflag) Parse() {
e.parseWithEnv(os.Args[1:])
}
// parseWithEnv first parses cli-values into flag-values. Next, for any unset
// flag-values, it attempts to lookup and load from environment variables, by flag-name.
func (e Envflag) parseWithEnv(args []string) {
if !e.Cli.Parsed() {
e.Cli.Parse(args)
}
for name := range e.unsetFlags() {
if val, ok := os.LookupEnv(maskEnvName(name)); ok {
e.Cli.Set(name, val)
}
}
}
// maskEnvName returns a qualified environement variable, naming convention.
func maskEnvName(flagname string) string {
var ret string
ret = strings.Replace(flagname, "-", "_", -1)
ret = strings.Replace(ret, ".", "_", -1)
return strings.ToUpper(ret)
}
// unsetFlags returns flag-values that hasn't been set via CLI.
func (e Envflag) unsetFlags() map[string]struct{} {
flags := make(map[string]struct{})
// get all flag-names.
e.Cli.VisitAll(func(f *flag.Flag) {
flags[f.Name] = struct{}{}
})
// MINUS from set flag-names.
e.Cli.Visit(func(f *flag.Flag) {
delete(flags, f.Name)
})
return flags
}
// Parse parses the command-line flags from os.Args[1:].
// Must be called after all flags are defined and before flags are accessed by the program.
func Parse() {
DefaultEnvflag.parseWithEnv(os.Args[1:])
}