-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdefaults.go
146 lines (122 loc) · 3.04 KB
/
defaults.go
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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
package dotenv
import (
"fmt"
"sort"
"strings"
"sync"
"time"
"github.com/fatih/color"
"golang.org/x/crypto/ssh/terminal"
)
const (
StringType = iota
StringSliceType
IntType
Float64Type
BoolType
DurationType
)
type descriptor struct {
Var string
DataType int
DefaultValue interface{}
Description string
}
// Cache default values for environment variables.
var registered = make(map[string]descriptor)
var regMutex sync.RWMutex
// Register registers a default value for an environment variable. When getting the value for that
// environment variable, if a value isn't set, the default is returned.
func Register(key string, defaultValue interface{}, description string) {
var dataType int
switch defaultValue.(type) {
case string:
dataType = StringType
case []string:
dataType = StringSliceType
case int:
dataType = IntType
case float64:
dataType = Float64Type
case bool:
dataType = BoolType
case time.Duration:
dataType = DurationType
default:
panic("invalid type")
}
registered[key] = descriptor{
Var: key,
DataType: dataType,
DefaultValue: defaultValue,
Description: description,
}
}
// Default returns the default setting set by the Register call. Thread-safe.
func Default(key string) (descriptor, bool) {
regMutex.RLock()
defer regMutex.RUnlock()
val, present := registered[key]
return val, present
}
// Colorized output
var (
keyColor = color.New(color.FgYellow)
typeColor = color.New(color.FgCyan)
defaultColor = color.New(color.FgWhite, color.Faint)
descColor = color.New(color.FgWhite)
typeNames = map[int]string{
StringType: "string",
StringSliceType: "[]string",
IntType: "integer",
Float64Type: "float",
BoolType: "boolean",
DurationType: "duration",
}
)
// Help displays details about registered default variables. May be called via a `--help`
// command-line parameter, or if some setting is invalid. Produces colorized output to stdout.
func Help() {
var keys []string
var width, descWidth, defvalWidth int
for key, d := range registered {
keys = append(keys, key)
if len(key) > width {
width = len(key)
}
if len(d.Description) > descWidth {
descWidth = len(d.Description)
}
w := len(fmt.Sprintf("%v", d.DefaultValue))
if w > defvalWidth {
defvalWidth = w
}
}
termWidth, _, err := terminal.GetSize(0)
if err != nil {
termWidth = 80
}
if width+descWidth+defvalWidth+18 > termWidth {
if defvalWidth > 20 {
defvalWidth = 20
}
descWidth = termWidth - width - defvalWidth - 18
}
sort.Strings(keys)
for _, key := range keys {
d := registered[key]
_, _ = keyColor.Print(pad(key, width))
fmt.Print(" ")
_, _ = typeColor.Print(pad(typeNames[d.DataType], 12))
fmt.Print(" ")
_, _ = descColor.Print(pad(d.Description, descWidth))
fmt.Print(" ")
_, _ = defaultColor.Println(pad(fmt.Sprintf("%v", d.DefaultValue), defvalWidth))
}
}
func pad(val string, width int) string {
if len(val) > width {
return val[:width-3] + "..."
}
return val + strings.Repeat(" ", width-len(val))
}