feat: allow setting empty env var value
parent
997e9611eb
commit
6678040d30
24
conf.v
24
conf.v
|
@ -17,20 +17,18 @@ pub struct LoadConfig {
|
|||
// looks for either `${env.prefix}${field_name.to_upper()}` or
|
||||
// `${env.prefix}${field_name.to_upper()}${env.file_suffix}`, returning the
|
||||
// contents of the file instead if the latter. If both or neither exist, the
|
||||
// function returns an error.
|
||||
fn (ld LoadConfig) get_env_var(field_name string) !string {
|
||||
// function returns an error. It returns two values, with the first indicating
|
||||
// whether the env vars were actually present.
|
||||
fn (ld LoadConfig) get_env_var(field_name string) !(bool, string) {
|
||||
env_var_name := '$ld.prefix$field_name.to_upper()'
|
||||
env_file_name := '$ld.prefix$field_name.to_upper()$ld.file_suffix'
|
||||
env_var := ld.env[env_var_name] or { '' }
|
||||
env_file := ld.env[env_file_name] or { '' }
|
||||
|
||||
// If both are missing, we return an empty string
|
||||
if env_var == '' && env_file == '' {
|
||||
return ''
|
||||
if env_var_name !in ld.env && env_file_name !in ld.env {
|
||||
return false, ''
|
||||
}
|
||||
|
||||
// If they're both set, we report a conflict
|
||||
if env_var != '' && env_file != '' {
|
||||
if env_var_name in ld.env && env_file_name in ld.env {
|
||||
return error('Only one of $env_var_name or $env_file_name can be defined.')
|
||||
}
|
||||
|
||||
|
@ -38,12 +36,12 @@ fn (ld LoadConfig) get_env_var(field_name string) !string {
|
|||
// I'm pretty sure this also prevents variable ending in _FILE (e.g.
|
||||
// VIETER_LOG_FILE) from being mistakingely read as an _FILE suffixed env
|
||||
// var.
|
||||
if env_var != '' {
|
||||
return env_var
|
||||
if env_var_name in ld.env {
|
||||
return true, ld.env[env_var_name]
|
||||
}
|
||||
|
||||
// Otherwise, we process the file
|
||||
return os.read_file(env_file) or {
|
||||
return true, os.read_file(ld.env[env_file_name]) or {
|
||||
error('Failed to read file defined in $env_file_name: ${err.msg()}.')
|
||||
}
|
||||
}
|
||||
|
@ -86,11 +84,11 @@ pub fn load<T>(ld LoadConfig) !T {
|
|||
}
|
||||
|
||||
$for field in T.fields {
|
||||
env_value := ld.get_env_var(field.name)!
|
||||
env_present, env_value := ld.get_env_var(field.name)!
|
||||
|
||||
// The value of an env var will always take precedence over the toml
|
||||
// file.
|
||||
if env_value != '' {
|
||||
if env_present {
|
||||
$if field.typ is string {
|
||||
res.$(field.name) = env_value
|
||||
} $else $if field.typ is int {
|
||||
|
|
117
string_test.v
117
string_test.v
|
@ -8,29 +8,47 @@ struct SingleConfDefault {
|
|||
some_string string = 'default'
|
||||
}
|
||||
|
||||
const env = {
|
||||
'SOME_STRING': 'env'
|
||||
}
|
||||
|
||||
const prefix_env = {
|
||||
'TEST_SOME_STRING': 'env'
|
||||
}
|
||||
|
||||
fn test_string_present_no_default() {
|
||||
conf := load<SingleConf>(default_path: 'test/string.toml')!
|
||||
assert conf == SingleConf{
|
||||
some_string: 'hi'
|
||||
}
|
||||
|
||||
conf2 := load<SingleConf>(default_path: 'test/string_empty.toml')!
|
||||
assert conf2 == SingleConf{
|
||||
some_string: ''
|
||||
}
|
||||
}
|
||||
|
||||
fn test_string_present_no_default_env() {
|
||||
conf := load<SingleConf>(default_path: 'test/string.toml', env: .env)!
|
||||
mut conf := load<SingleConf>(
|
||||
default_path: 'test/string.toml'
|
||||
env: {
|
||||
'SOME_STRING': 'env'
|
||||
}
|
||||
)!
|
||||
assert conf == SingleConf{
|
||||
some_string: 'env'
|
||||
}
|
||||
|
||||
conf2 := load<SingleConf>(default_path: 'test/string.toml', env: .prefix_env, prefix: 'TEST_')!
|
||||
assert conf2 == SingleConf{
|
||||
conf = load<SingleConf>(
|
||||
default_path: 'test/string.toml'
|
||||
env: {
|
||||
'SOME_STRING': ''
|
||||
}
|
||||
)!
|
||||
assert conf == SingleConf{
|
||||
some_string: ''
|
||||
}
|
||||
|
||||
conf = load<SingleConf>(
|
||||
default_path: 'test/string.toml'
|
||||
env: {
|
||||
'TEST_SOME_STRING': 'env'
|
||||
}
|
||||
prefix: 'TEST_'
|
||||
)!
|
||||
assert conf == SingleConf{
|
||||
some_string: 'env'
|
||||
}
|
||||
}
|
||||
|
@ -41,13 +59,34 @@ fn test_string_absent_no_default() {
|
|||
}
|
||||
|
||||
fn test_string_absent_no_default_env() {
|
||||
conf := load<SingleConf>(default_path: 'test/string.toml', env: .env)!
|
||||
mut conf := load<SingleConf>(
|
||||
default_path: 'test/string.toml'
|
||||
env: {
|
||||
'SOME_STRING': 'env'
|
||||
}
|
||||
)!
|
||||
assert conf == SingleConf{
|
||||
some_string: 'env'
|
||||
}
|
||||
|
||||
conf2 := load<SingleConf>(default_path: 'test/string.toml', env: .prefix_env, prefix: 'TEST_')!
|
||||
assert conf2 == SingleConf{
|
||||
conf = load<SingleConf>(
|
||||
default_path: 'test/string.toml'
|
||||
env: {
|
||||
'SOME_STRING': ''
|
||||
}
|
||||
)!
|
||||
assert conf == SingleConf{
|
||||
some_string: ''
|
||||
}
|
||||
|
||||
conf = load<SingleConf>(
|
||||
default_path: 'test/string.toml'
|
||||
env: {
|
||||
'TEST_SOME_STRING': 'env'
|
||||
}
|
||||
prefix: 'TEST_'
|
||||
)!
|
||||
assert conf == SingleConf{
|
||||
some_string: 'env'
|
||||
}
|
||||
}
|
||||
|
@ -60,17 +99,34 @@ fn test_string_present_default() {
|
|||
}
|
||||
|
||||
fn test_string_present_default_env() {
|
||||
conf := load<SingleConfDefault>(default_path: 'test/string.toml', env: .env)!
|
||||
mut conf := load<SingleConfDefault>(
|
||||
default_path: 'test/string.toml'
|
||||
env: {
|
||||
'SOME_STRING': 'env'
|
||||
}
|
||||
)!
|
||||
assert conf == SingleConfDefault{
|
||||
some_string: 'env'
|
||||
}
|
||||
|
||||
conf2 := load<SingleConfDefault>(
|
||||
conf = load<SingleConfDefault>(
|
||||
default_path: 'test/string.toml'
|
||||
env: .prefix_env
|
||||
env: {
|
||||
'SOME_STRING': ''
|
||||
}
|
||||
)!
|
||||
assert conf == SingleConfDefault{
|
||||
some_string: ''
|
||||
}
|
||||
|
||||
conf = load<SingleConfDefault>(
|
||||
default_path: 'test/string.toml'
|
||||
env: {
|
||||
'TEST_SOME_STRING': 'env'
|
||||
}
|
||||
prefix: 'TEST_'
|
||||
)!
|
||||
assert conf2 == SingleConfDefault{
|
||||
assert conf == SingleConfDefault{
|
||||
some_string: 'env'
|
||||
}
|
||||
}
|
||||
|
@ -83,17 +139,34 @@ fn test_string_absent_default() {
|
|||
}
|
||||
|
||||
fn test_string_absent_default_env() {
|
||||
conf := load<SingleConfDefault>(default_path: 'test/empty.toml', env: .env)!
|
||||
mut conf := load<SingleConfDefault>(
|
||||
default_path: 'test/empty.toml'
|
||||
env: {
|
||||
'SOME_STRING': 'env'
|
||||
}
|
||||
)!
|
||||
assert conf == SingleConfDefault{
|
||||
some_string: 'env'
|
||||
}
|
||||
|
||||
conf2 := load<SingleConfDefault>(
|
||||
conf = load<SingleConfDefault>(
|
||||
default_path: 'test/empty.toml'
|
||||
env: .prefix_env
|
||||
env: {
|
||||
'SOME_STRING': ''
|
||||
}
|
||||
)!
|
||||
assert conf == SingleConfDefault{
|
||||
some_string: ''
|
||||
}
|
||||
|
||||
conf = load<SingleConfDefault>(
|
||||
default_path: 'test/empty.toml'
|
||||
env: {
|
||||
'TEST_SOME_STRING': 'env'
|
||||
}
|
||||
prefix: 'TEST_'
|
||||
)!
|
||||
assert conf2 == SingleConfDefault{
|
||||
assert conf == SingleConfDefault{
|
||||
some_string: 'env'
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
some_int = "hi"
|
|
@ -0,0 +1 @@
|
|||
some_string = ""
|
Loading…
Reference in New Issue