Support for reading .env files
I've noticed that .add_source(config::File::with_name(".env")) does not work because .env "is not of a registered file format"
I think this library should support reading .env files, as well as .env.prod, etc.. files
Let me know what you think, I could submit a PR for this
Another thing to note: config::File::new(".env", FileFormat::Ini) does not work either because it skips normalizing the casing (.env contains uppercase variables, and I think the library expects lower case ones, unlike Environment::default())
I'd say this is a "bug" (or an improvement to be made) even if we don't consider env files, since I don't see why we should have separate configuration keys for e.g. S3_ACCESS_KEY and s3_access_key
I could see having a distinct format for .env to allow for the case normalization that we do for env variables.
I would like to see a quick summary of expectations for env support to identify anything that needs more discussion.
I think the .env file should be able to handle quotes (SERVER_URL="http://localhost:9000"
Apart from that and converting to lower case, I don't think any special treatment is required
Env files are not standardised (?) and I don't think we need to bother with advanced features like variable interpolation for a first implementation
Is there a general expectation for their naming or how they are discovered?
I think we should detect files like .env.prod (note that the extension is not .env) as env files, because other ecosystems tend to name them like this (e.g. https://nextjs.org/docs/pages/guides/environment-variables#test-environment-variables)
So the format would be .env[.*] (so it will lead to custom code in find_file to handle it)
I am thinking of using https://github.com/allan2/dotenvy to handle parsing. Want me to submit a PR ?
Note for users wanting a solution right now: I was able to somewhat achieve it with .add_source(config::File::from_str(&std::fs::read_to_string(".env")?.to_lowercase(), FileFormat::Ini).required(true))
If we are reading in .env[.*], what happens if there are multiple.
Sounds like we shouldn't load both.
Some options
- error
- first in reverse alphabetical order
- have users give concrete set of names in precedence order
I think we should leave the choice to the user as to which file(s) to load. The way I see it, we would add a FileFormat::Env variant and let the use choose which file to use. If he wishes to load a different env file based on the context (debug vs preprod vs prod, etc..), he will have to implement that mechanism himself (not like we could choose for him if we should load debug or prod configuration)
So the resulting code would look like .add_source(config::File::new(".env")) (with Env file type being detected from the name) in most cases. .env[.*] would only be used to determine the file type of the file already provided by the user.
Sounds reasonable. Let's give this a shot.
@iTrooz You can use dotenvy