-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathenv.go
139 lines (114 loc) · 2.47 KB
/
env.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
package env
import (
"encoding/json"
"fmt"
"os"
"strings"
"sync"
"github.com/rocketbitz/set"
)
var (
s = set.NewUnsafe()
l sync.RWMutex
)
func init() {
l.Lock()
for _, pair := range os.Environ() {
keyValue := strings.Split(pair, "=")
s.Add(Var{Key: keyValue[0], Value: keyValue[1]})
}
l.Unlock()
}
// Var represents an environment variable,
// default or set by the environment itself
type Var struct {
Key string `json:"key"`
Value string `json:"value"`
Default bool `json:"default,omitempty"`
}
// SetDefault registers a string as a default
// value for an environment variable
func SetDefault(key, value string) {
l.Lock()
s.Add(Var{Key: key, Value: value, Default: true})
l.Unlock()
}
// SetDefaults registers a map[string]string as
// default values for environment variables
func SetDefaults(defaults map[string]string) {
l.Lock()
for k, v := range defaults {
s.Add(Var{Key: k, Value: v, Default: true})
}
l.Unlock()
}
// Set an environment variable, returns true
// if the value was already set by either
// default or the environment itself
func Set(key, value string) bool {
l.Lock()
defer l.Unlock()
for _, v := range s.Slice() {
ev := v.(Var)
if ev.Key == key {
return s.Replace(ev, Var{Key: key, Value: value})
}
}
s.Add(Var{Key: key, Value: value})
return false
}
// Get a given environment variable by name,
// returns a default value if the variable
// is not set
func Get(key string) (value string) {
l.RLock()
defer l.RUnlock()
for _, v := range s.Slice() {
ev := v.(Var)
if ev.Key == key {
return ev.Value
}
}
return ""
}
// Count the number of environment variables
// set, default and explicit
func Count() int {
return s.Len()
}
// DefaultCount is the number of environment
// variables, defaults only
func DefaultCount() (count int) {
l.RLock()
defer l.RUnlock()
for _, v := range s.Slice() {
if v.(Var).Default {
count++
}
}
return
}
// ExplicitCount is the number of environment
// variables, explicit only
func ExplicitCount() int {
return Count() - DefaultCount()
}
// JSON representation of the environment,
// defaults included
func JSON() []byte {
tmp := make([]Var, s.Len())
for i, v := range s.Slice() {
tmp[i] = v.(Var)
}
buf, _ := json.MarshalIndent(tmp, "", "\t")
return buf
}
// String representation (in JSON) of the
// environment, defaults included
func String() string {
return string(JSON())
}
// Print the environment, defaults included
func Print() {
fmt.Println(String())
}