-
Notifications
You must be signed in to change notification settings - Fork 6
/
env.go
78 lines (71 loc) · 1.58 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
package commands
import (
"bytes"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"sync"
)
var envCache struct {
once sync.Once
m map[string]string
}
// EnvFile returns the name of the Go environment configuration file.
func EnvFile() (string, error) {
if file := os.Getenv("GOENV"); file != "" {
if file == "off" {
return "", fmt.Errorf("GOENV=off")
}
return file, nil
}
dir, err := os.UserConfigDir()
if err != nil {
return "", err
}
if dir == "" {
return "", fmt.Errorf("missing user-config dir")
}
return filepath.Join(dir, "go/env"), nil
}
func initEnvCache() {
envCache.m = make(map[string]string)
file, _ := EnvFile()
if file == "" {
return
}
data, err := ioutil.ReadFile(file)
if err != nil {
return
}
for len(data) > 0 {
// Get next line.
line := data
i := bytes.IndexByte(data, '\n')
if i >= 0 {
line, data = line[:i], data[i+1:]
} else {
data = nil
}
i = bytes.IndexByte(line, '=')
if i < 0 || line[0] < 'A' || 'Z' < line[0] {
// Line is missing = (or empty) or a comment or not a valid env name. Ignore.
// (This should not happen, since the file should be maintained almost
// exclusively by "go env -w", but better to silently ignore than to make
// the go command unusable just because somehow the env file has
// gotten corrupted.)
continue
}
key, val := line[:i], line[i+1:]
envCache.m[string(key)] = string(val)
}
}
// Getenv gets the value from env or configuration.
func Getenv(key string) string {
val := os.Getenv(key)
if val != "" {
return val
}
envCache.once.Do(initEnvCache)
return envCache.m[key]
}