-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgoenv.go
102 lines (82 loc) · 2.12 KB
/
goenv.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
package goenv
import (
"os"
"path/filepath"
"strconv"
"strings"
)
const (
EnvFile = ".env"
)
// getPaths converts an array of directory entries into an array of file paths by concatenating each
// entry's name with a base path.
func getPaths(newDirs []os.DirEntry, basePath string) []string {
paths := make([]string, len(newDirs))
for i, dir := range newDirs {
paths[i] = filepath.Join(basePath, dir.Name())
}
return paths
}
// loadVarsFromFile parses an .env file at the given path and loads its variables into the environment.
func loadVarsFromFile(path string) error {
fileData, err := os.ReadFile(path)
if err != nil {
return err
}
for _, line := range strings.Split(string(fileData), "\n") {
if line == "" || strings.HasPrefix(line, "#") {
continue
}
parts := strings.Split(line, "=")
if len(parts) == 2 {
key, value := strings.TrimSpace(parts[0]), strings.TrimSpace(parts[1])
if err := os.Setenv(key, value); err != nil {
return err
}
}
}
return nil
}
// Load recursively scans all directories of a project until it finds a .env file. Once found, it reads
// the file and loads its values as environment variables.
func Load() error {
dirsQueue := []string{"./"}
for len(dirsQueue) > 0 {
path := dirsQueue[0]
file, err := os.Stat(path)
if err != nil {
return err
}
if file.IsDir() {
children, err := os.ReadDir(path)
if err != nil {
return err
}
dirsQueue = append(dirsQueue, getPaths(children, path)...)
} else if file.Name() == EnvFile {
return loadVarsFromFile(path)
}
dirsQueue = dirsQueue[1:]
}
return nil
}
// GetString returns the value of an environment variable if it exists; otherwise, it returns the fallback value.
func GetString(key, fallback string) string {
val, ok := os.LookupEnv(key)
if !ok {
return fallback
}
return val
}
// GetInt returns the integer value of an environment variable if it exists; otherwise, it returns the fallback value.
func GetInt(key string, fallback int) int {
val, ok := os.LookupEnv(key)
if !ok {
return fallback
}
intVal, err := strconv.Atoi(val)
if err != nil {
return fallback
}
return intVal
}