Open Mechite opened 1 year ago
Extended proposal Serialising from a pure environment variable is difficult as there are no primitives for lists and such. Therefore, I propose that we parse environment variables with a JSON-like syntax mixed with whatever configuration language the user might be using for the larger types.
server.identifier
= Hello, world!
server.port
= 8080
server.production
= true
example.settings
= { port: 8080, identifier: "Hello, world!" }
server.seeds
= [8080, 8090]
.This is not trivial to parse strings like this but it would be a very useful feature. Arrays are likely going to be required to make environment variables a useful way to override configuration, but objects are quite useless if you can just make multiple qualifying environment variables, so do not need to be implemented. Either way, languages like TOML may it impossible to do things this way, so I'm really unsure how easy it will be to make it support the user's chosen markup, or if JSON should be the only option here.
yes, that would be a nice feature to offer! Thank you for the proposal. We could take inspiration from clap here (also available in "derive" mode, which is analogous to NightConfig's annotations in terms of usage).
Alright so a little change to the proposal (I'm not familiar with clap and don't know if that has its own, better semantics for this)
Arrays in environment variables should not be parsed like that but instead should be lists separated with semicolons (;
) as this is the idiomatic way to do it on all platforms (see PATH
).
An array containing objects should be achievable by passing the users' configuration language in, i.e. this is what it would look like to pass an object in:
EXAMPLE={ name: "Mr Raffin", age: null }
and this is what it would look like to pass an array of objects:
EXAMPLE={ name: "Mr Raffin", age: null };{ name: "Mechite", age: 127 }
Given they are using a language that requires new lines, etc for this, escape codes can be used directly, and if the semicolon would normally be parsed by the language (a lot of these languages don't define start and EOF like JSON), it can be escaped too, i.e. with YAML:
EXAMPLE=name: Mr Raffin\nage: ~\;name: Mechite\nage: 127
which is basically just an escaped semicolon between these two YAML files:
name: Mr Raffin
age: ~
name: Mechite
age: 127
I feel like using objects/documents in environment variables is a very rare use case, but having support for it is ideal, and I think having a standard way of defining arrays is better simply because they are going to be used every often, e.g:
HOSTS=127.0.0.1:8080;172.17.0.1:8080
Implementary notes Should be available on builder classes, etc, as configuration options for loading configurations.
Expected behaviour When a qualifier in the configuration, e.g.
server.port
is set as an environment variable (should be case insensitive), it should be the preferred value in the configuration when this feature is enabled. If the environment variable cannot be parsed correctly when requested, by anObjectConverter
or by aget*
method, the value from the configuration file is used as a fallback.Motivation
night-config
provides a great way for efficiency in development environments, especially with auto updating, etc. Large, scalable environments tend to prefer environment variables for configuration, e.g. Docker on k8s.