-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.n
More file actions
130 lines (109 loc) · 3.73 KB
/
main.n
File metadata and controls
130 lines (109 loc) · 3.73 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
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
import fs
import fmt
import strings
import syscall
import "env.n" as env
import "parser.n" as *
import "utils.n" as *
const DOUBLE_QUOTE_SPECIAL_CHARS = '\\\n\r"!$`'
// unmarshal reads an env string and returns a map of keys and values.
fn unmarshal(string src):{string:string}! {
return unmarshal_bytes(src)
}
// unmarshal_bytes parses env file content, returning a map of keys and values.
fn unmarshal_bytes(string src):{string:string}! {
{string:string} out = {}
parse_bytes(src, out)
return out
}
// read reads all env vars from the specified files and returns them as a map
// without loading them into the process environment.
// If no filenames given, defaults to ".env".
fn read(...[string] filenames):{string:string}! {
var fnames = filenames_or_default(filenames)
{string:string} env_map = {}
for fname in fnames {
var individual = read_file(fname)
for k, v in individual {
env_map[k] = v
}
}
return env_map
}
// load reads env file(s) and loads them into the process environment.
// It WILL NOT override env variables that already exist.
// If no filenames given, defaults to ".env".
// Panics on failure.
fn load(...[string] filenames):bool {
var fnames = filenames_or_default(filenames)
for fname in fnames {
load_file(fname, false) catch err {
panic(fmt.sprintf('failed to load env file "%s": %s', fname, err.msg()))
}
}
return true
}
// overload reads env file(s) and loads them into the process environment.
// It WILL override env variables that already exist.
// If no filenames given, defaults to ".env".
// Panics on failure.
fn overload(...[string] filenames):bool {
var fnames = filenames_or_default(filenames)
for fname in fnames {
load_file(fname, true) catch err {
panic(fmt.sprintf('failed to load env file "%s": %s', fname, err.msg()))
}
}
return true
}
// write serializes the given environment map and writes it to a file.
// Each line is in the format: KEY="VALUE" (with escaping) or KEY=123 for integers.
fn write({string:string} env_map, string filename):void! {
var content = marshal(env_map) + '\n'
var f = fs.open(filename, syscall.O_WRONLY | syscall.O_CREAT | syscall.O_TRUNC, 0o644)
f.write(content as [u8])
f.close()
}
// marshal outputs the given environment map as a dotenv-formatted string.
// Each line is in the format: KEY="VALUE" where VALUE is backslash-escaped,
// or KEY=VALUE for pure integer values.
fn marshal({string:string} env_map):string {
[string] lines = []
for k, v in env_map {
if is_integer(v) {
lines.push(k + '=' + v)
} else {
lines.push(k + '="' + double_quote_escape(v) + '"')
}
}
sort_strings(lines)
return join_strings(lines, '\n')
}
// text retrieves an env var as a string.
fn text(string key, ...[string] fallback):string! {
return env.text(key, ...fallback)
}
// str is an alias for text.
fn str(string key, ...[string] fallback):string! {
return env.str(key, ...fallback)
}
// number retrieves an env var as an int.
fn number(string key, ...[int] fallback):int! {
return env.number(key, ...fallback)
}
// decimal retrieves an env var as a float.
fn decimal(string key, ...[float] fallback):float! {
return env.decimal(key, ...fallback)
}
// boolean retrieves an env var as a bool.
fn boolean(string key, ...[bool] fallback):bool! {
return env.boolean(key, ...fallback)
}
// array retrieves an env var as a string array.
fn array(string key, ...[string] fallback):[string]! {
return env.array(key, ...fallback)
}
// dict retrieves an env var as a key/value map.
fn dict(string key, ...[string] fallback):{string:string}! {
return env.dict(key, ...fallback)
}