Go library for loading env files and resolving environmental variables.
ResolveEnv: resolves environmental variables.LoadEnv: loads env file.EnvSubst: substitutes environmental variables in a text.EnvSubst2: recursively substitutes environmental variables in a text.
This library is originally the fork of aileron-projects/go.
go get github.com/k7a-tomohiro/go-env@latest
ResolveEnv substitutes a single environmental variable expression. Supported expressions are listed below. Expressions are basically derived from shell parameter substitution. Note that the substitution behavior is NOT exactly the same as bash.
Example:
os.Setenv("ABC", "abcdefg")
os.Setenv("FOO", "foo")
os.Setenv("BAR", "BAR")
os.Setenv("ARR_X", "xxx")
os.Setenv("ARR_Y", "yyy")
env.ResolveEnv([]byte("${FOO}")) // foo
env.ResolveEnv([]byte("${BAZ:-default}")) // default
env.ResolveEnv([]byte("${BAZ-default}")) // default
env.ResolveEnv([]byte("${BAZ:=default}")) // default
env.ResolveEnv([]byte("${BAZ=default}")) // default
env.ResolveEnv([]byte("${BAZ:?default}")) // default
env.ResolveEnv([]byte("${BAZ?default}")) // default
env.ResolveEnv([]byte("${BAZ:+default}")) // default
env.ResolveEnv([]byte("${BAZ+default}")) // default
env.ResolveEnv([]byte("${ABC:3}")) // defg
env.ResolveEnv([]byte("${ABC:3:3}")) // def
env.ResolveEnv([]byte("${!ARR*}")) // ARR_X ARR_Y
env.ResolveEnv([]byte("${!ARR@}")) // ARR_X ARR_Y
env.ResolveEnv([]byte("${#FOO}")) // 3
env.ResolveEnv([]byte("${FOO#[a-z]}")) // oo
env.ResolveEnv([]byte("${FOO##[a-z]}")) // oo
env.ResolveEnv([]byte("${FOO%[a-z]}")) // fo
env.ResolveEnv([]byte("${FOO%%[a-z]}")) // fo
env.ResolveEnv([]byte("${FOO/[a-z]/x}")) // xoo
env.ResolveEnv([]byte("${FOO//[a-z]/x}")) // xxx
env.ResolveEnv([]byte("${FOO/#[a-z]/x}")) // xoo
env.ResolveEnv([]byte("${FOO/%[a-z]/x}")) // fox
env.ResolveEnv([]byte("${FOO^[f]}")) // Foo
env.ResolveEnv([]byte("${FOO^^[o]}")) // fOO
env.ResolveEnv([]byte("${BAR,[B]}")) // bAR
env.ResolveEnv([]byte("${BAR,,[A]}")) // BaR
env.ResolveEnv([]byte("${FOO@U}")) // FOOSee the ResolveEnv for full docs.
EnvSubst substitute environmental variable in the given bytes. See the ResolveEnv for available variable syntax. EnvSubst does not support nested variables. Use EnvSubst2 to allow 2 levels nested variable. Note that escaping variable like '${FOO}' is not supported.
Example:
os.Setenv("FOO", "foo")
os.Setenv("BAR", "FOO")
env.EnvSubst([]byte(`{FOO}=${FOO}`)) // {FOO}=foo
env.EnvSubst([]byte(`{{BAR}}=${${BAR}}`)) // {{BAR}}=${FOO}See the EnvSubst for full docs.
EnvSubst2 substitute environmental variable in the given bytes. See the ResolveEnv for available variable syntax. EnvSubst does support nested variables up to 2 levels. ${FOO_${BAR}} is allowed but ${FOO_${BAR_${BAZ}}}} is not allowed. Note that escaping variable like '${FOO}' is not supported.
Example:
os.Setenv("FOO", "foo")
os.Setenv("BAR", "FOO")
env.EnvSubst2([]byte(`{FOO}=${FOO}`)) // {FOO}=foo
env.EnvSubst2([]byte(`{{BAR}}={FOO}=${${BAR}}`)) // {{BAR}}={FOO}=fooSee the EnvSubst2 for full docs.
LoadEnv loads environmental variable from the given bytes. Typically, LoadEnv is used for loading .env file. LoadEnv resolves embedded environmental variables in a env file. The syntax for substituting environmental variable follows the specification of ResolveEnv.
Envs are resolved by following the rules below.
Single line:
# Following declaration results in BAR.
# Single quotes and double quotes are removed if entire value is enclosed.
# "export" can be placed before env name.
FOO=BAR >> BAR
FOO="BAR" >> BAR
FOO='BAR' >> BAR
FOO='B"R' >> B"R
FOO="B'R" >> B'R
export FOO=BAR >> BAR
Multiple line:
# The following definition of FOO results in "BARBAZ".
# Line breaks of LF or CRLF are removed.
# BOTH single quotes and double quotes can be used to enclose multiple lines.
FOO="
BAR
BAZ
"
Comments:
# Sharp '#' can be used for commenting.
# It must not be in the scope of single or double quotes.
# It must have at least 1 white space before '#' if the comment is after value.
# comment >> Comment is appropriately parsed.
FOO=BAR # comment >> Comment is appropriately parsed.
FOO=BAR# comment >> '#' is not parsed as comment. It considered as a part of value.
Escapes:
# '\\' can be used for escaping character following the 3 rules.
# 1. '\\' always escapes special character of ', ", \\, #
# 2. '\\' is ignored when it is not in the scope of single or double quotes.
# 3. '\\'n or "\n" in the scope of single or doubles quotes results in line breaks of LF.
FOO=B\"R >> B"R
FOO=B\'R >> B'A
FOO="B\"R" >> B"R
FOO=B\R >> BR (Its not in a scope of single or double quotes.)
FOO="B\nR" >> B<LF>R (\n is, if in a scope of quotes, converted into a line break.)
Environmental variables:
# LoadEnv resolves environmental variables.
FOO=BAR${BAZ}
Example:
b, _ := os.ReadFile(".env")
kv, err := LoadEnv(b)
for k, v := range kv{
fmt.Println(k,v)
}See the LoadEnv for full docs.