dotenv-rs / dotenv Goto Github PK
View Code? Open in Web Editor NEWLibrary to help supply environment variables in testing and development
License: MIT License
Library to help supply environment variables in testing and development
License: MIT License
Would you consider adding support for dotenv-flow?
If so, I can issue a pull request that adds a "dotenv_flow()" function that implements the alternative loading strategy. This way the end user can decide whether to use the classic "dotenv()" function (that would remain untouched) or the flow variant.
It would be really awesome to have this as a binary that could run like this:
dotenv .env -- someprogram --foo bar
Do you have any interest in supporting that? I'd be willing to help.
Hello,
Unfortunately archives stored on crates.io which are used when relying on dotenv from Cargo.toml do not contain LICENSE.md file which is requirement.
This can be solved by copying it in all sub-crates folders or adding symlink in the same place. I am not sure which way you prefer, so no PR.
Thanks in advance!
the line
ROCKET_DATABASES='db={url=foo.sqlite}'
fails regardless of whether I surround with single or double quotes. I tried escaping the equals signs with backslashes, but that didn't help either.
Please support default substitution like this:
https://docs.docker.com/compose/compose-file/#variable-substitution
${VARIABLE:-default}
evaluates to default ifVARIABLE
is unset or empty in the environment.
${VARIABLE-default}
evaluates to default only ifVARIABLE
is unset in the environment.
I miss one thing that could be helpful for others -- there is no way the library would override existing env variable via .env
file. Sometimes it is needed though.
For example, I'd like to override PATH
. If I create a file .env
with PATH=/opt/bin:${PATH}
that would have no effect.
Did you consider any modificator for KEY? Maybe, !
? That could mean to override existing env variable.
In my case that would be !PATH=/opt/bin:${PATH}
.
What do you think?
I have a proposal to better coordinate the deployment of containers. When we are developing locally, one .env
configuration file may be sufficient, but when containers are used, multiple configuration files are often required to be used together.
For example, .envs/.mysql
is to provide mysql deployment configure, and .envs/.redis
is to provide redis configuration deployment configure。
use std::env;
fn main() {
// Read all configuration files in the following directory
// .envs
// .envs/.elasticsearch
// .envs/.redis
// .envs/mysql
// .envs/mysql/.mysql2
// .envs/mysql/.mysql1
use dotenv;
dotenv::dotenvs().ok();
for (key, value) in env::vars() {
println!("{}: {}", key, value);
}
}
In this way, I developed well with docker-compose.
I have implemented the logic, if it feels good, I will PR.
I just find out zenv
and its CLI feature help me a lot. Would we get a standalone CLI too?
Compiling dotenv v0.15.0
Running `CARGO=/usr/local/bin/cargo CARGO_CRATE_NAME=dotenv CARGO_MANIFEST_DIR=/wrkdirs/usr/ports/deskutils/just/work/just-1.6.0/cargo-crates/dotenv-0.15.0 CARGO_PKG_AUTHORS='Noemi Lapresta <[email protected]>:Craig Hills <[email protected]>:Mike Piccolo <[email protected]>:Alice Maz <[email protected]>:Sean Griffin <[email protected]>:Adam Sharp <[email protected]>:Arpad Borsos <[email protected]>' CARGO_PKG_DESCRIPTION='A `dotenv` implementation for Rust' CARGO_PKG_HOMEPAGE='https://github.com/dotenv-rs/dotenv' CARGO_PKG_LICENSE=MIT CARGO_PKG_LICENSE_FILE='' CARGO_PKG_NAME=dotenv CARGO_PKG_REPOSITORY='https://github.com/dotenv-rs/dotenv' CARGO_PKG_RUST_VERSION='' CARGO_PKG_VERSION=0.15.0 CARGO_PKG_VERSION_MAJOR=0 CARGO_PKG_VERSION_MINOR=15 CARGO_PKG_VERSION_PATCH=0 CARGO_PKG_VERSION_PRE='' LD_LIBRARY_PATH='/wrkdirs/usr/ports/deskutils/just/work/target/release/deps:/usr/local/lib' /usr/local/bin/rustc --crate-name dotenv --edition=2018 /wrkdirs/usr/po
rts/deskutils/just/work/just-1.6.0/cargo-crates/dotenv-0.15.0/src/lib.rs --error-format=json --json=diagnostic-rendered-ansi,artifacts,future-incompat --crate-type lib --emit=dep-info,metadata,link -C opt-level=3 -C linker-plugin-lto -C metadata=6c5e365bdf4ca6c0 -C extra-filename=-6c5e365bdf4ca6c0 --out-dir /wrkdirs/usr/ports/deskutils/just/work/target/armv7-unknown-freebsd/release/deps --target armv7-unknown-freebsd -C linker=cc -L dependency=/wrkdirs/usr/ports/deskutils/just/work/target/armv7-unknown-freebsd/release/deps -L dependency=/wrkdirs/usr/ports/deskutils/just/work/target/release/deps --cap-lints warn -C link-arg=-fstack-protector-strong`
warning: use of deprecated constant `std::sync::ONCE_INIT`: the `new` function is now preferred
--> /wrkdirs/usr/ports/deskutils/just/work/just-1.6.0/cargo-crates/dotenv-0.15.0/src/lib.rs:17:23
|
17 | use std::sync::{Once, ONCE_INIT};
| ^^^^^^^^^
|
= note: `#[warn(deprecated)]` on by default
warning: use of deprecated constant `std::sync::ONCE_INIT`: the `new` function is now preferred
--> /wrkdirs/usr/ports/deskutils/just/work/just-1.6.0/cargo-crates/dotenv-0.15.0/src/lib.rs:23:22
|
23 | static START: Once = ONCE_INIT;
| ^^^^^^^^^
|
help: replace the use of the deprecated constant
|
23 | static START: Once = Once::new();
| ~~~~~~~~~~~
warning: `dotenv` (lib) generated 2 warnings
Compiling target v2.0.0
Running `CARGO=/usr/local/bin/cargo CARGO_CRATE_NAME=target CARGO_MANIFEST_DIR=/wrkdirs/usr/ports/deskutils/just/work/just-1.6.0/cargo-crates/target-2.0.0 CARGO_PKG_AUTHORS='Casey Rodarmor <[email protected]>' CARGO_PKG_DESCRIPTION='Get information on compilation target' CARGO_PKG_HOMEPAGE='https://github.com/casey/target' CARGO_PKG_LICENSE=CC0-1.0 CARGO_PKG_LICENSE_FILE='' CARGO_PKG_NAME=target CARGO_PKG_REPOSITORY='' CARGO_PKG_RUST_VERSION='' CARGO_PKG_VERSION=2.0.0 CARGO_PKG_VERSION_MAJOR=2 CARGO_PKG_VERSION_MINOR=0 CARGO_PKG_VERSION_PATCH=0 CARGO_PKG_VERSION_PRE='' LD_LIBRARY_PATH='/wrkdirs/usr/ports/deskutils/just/work/target/release/deps:/usr/local/lib' /usr/local/bin/rustc --crate-name target /wrkdirs/usr/ports/deskutils/just/work/just-1.6.0/cargo-crates/target-2.0.0/src/lib.rs --error-format=json --json=diagnostic-rendered-ansi,artifacts,future-incompat --crate-type lib --emit=dep-info,metadata,link -C opt-level=3 -C linker-plugin-lto -C metadata=545826272a4c6b18 -C ext
ra-filename=-545826272a4c6b18 --out-dir /wrkdirs/usr/ports/deskutils/just/work/target/armv7-unknown-freebsd/release/deps --target armv7-unknown-freebsd -C linker=cc -L dependency=/wrkdirs/usr/ports/deskutils/just/work/target/armv7-unknown-freebsd/release/deps -L dependency=/wrkdirs/usr/ports/deskutils/just/work/target/release/deps --cap-lints warn -C link-arg=-fstack-protector-strong`
error[E0308]: mismatched types
The error occurred during build of the Just project.
Log: https://pkg-status.freebsd.org/ampere2/data/main-armv7-default/pf323e9d40f68_s41be508d31/logs/just-1.6.0_2.log (IPv6 URL)
rust-1.65.0
OS: FreeBSD 13.1
Hello, I call the dotenv().ok();
on my main.rs
and it works well with the std::env::var()
. However, it seems not working when I use the option_env!
macro. Is it the expected behaviour?
I once had an use-case where a String (instead of strictly a file/args) would need to be parsed.
Is it possible to expose an API for String parsing?
The rules are different in the shell and in dotenv. This is confusing. Is it possible to adopt the shell rules?
These rules apply to dotenv (from the README
):
VAR=one
VAR_2=two
# Curly braces are useful in cases when we need to use a variable with non-alphanumeric name
RESULT=$VAR_2 #value: 'one_2' since $ with no curly braces stops after first non-alphanumeric symbol
RESULT=${VAR_2} #value: 'two'
In Bourne shell the rules are different:
VAR=one
VAR_2=two
RESULT=$VAR_2 #value: 'two' since $ with no curly braces uses as much as possible
RESULT=${VAR_2} #value: 'two' same thing
RESULT=${VAR}_2 #value: 'one_2', the curly brace mark the end of the variable name
When the .env file is saved with something other than a UTF-8 encoding, the initialization returns a NotFound custom error, which gives users the wrong lead when debugging.
Another error should be returned instead (wrong encoding).
Thanks very much for this crate.
The examples in the README
and the documentation all show using dotenv::dotenv().ok()
or dotenv::from_filename("custom.env").ok()
. The .ok()
causes dotenv
to silently ignore errors in loading the environment file. Perhaps that should have been obvious to me, but it wasn't, especially when I first started using the crate a few months ago. Given how explicit Rust typically is with errors, this wasn't the behavior I expected. I've learned my lesson, but wondered if others might also have been confused.
I understand not wanting to have full error handling in examples, but the most common way I've seen this handled in the Rust ecosystem is to use expect
. Would you be open to changing the documentation examples to something like dotenv::dotenv().expect("Could not open .env file")
? If so, I'd be happy to submit a PR.
Hello I'm making smart contracts via ink!rust and using
dotenv` as well.
While locally testing in my file directory I can reference my .env
file so all is fine, but when I deploy I have to drag and drop the <contract name>.contract
into the polkadot UI to deploy.
When this happens, it seems like the .env
file variables are no longer available. I want to restrict access of the smart contracts to only users who know an access mnemonic (like a pass code) so that everyone can't just spam the smart contract.
my current implementation uses dotenv
to read the mnemonic saved in the .env
file, but after noticing the above, I don't think this will work.
Is there a way to include the .env
metadata into the files generated by cargo +nightly contract build
?
if not, how else can I limit the access of the smart contract? I guess I can check for the caller address = contract address and only allow the contract's private key to signAndSend
a transaction which would mean I need to deploy the contract in my code so I can immediately grab the ABI and Address. But then I get this recursive issue of the address that I want to check against would not be defined until the contract is deployed, but when the contract is deployed it is assigned a new address and therefore keyring.
what should I do?
here is my implementation so far:
Overriding local .env
variables with system global variables, Is it intentional?
I am asking so, because there might be cases where you don't have the authority to override the system variables, but still want to use a local variable with same name in your application, where local variable should override the system variable instead.
Currently this forwards the underlying std::env::VarError
which has very unhelpful error messages: https://doc.rust-lang.org/src/std/env.rs.html#274-283
Namely, it doesn't report the variable that caused the error, which is useless for almost all intents and purposes unless you only ever invoke exactly it once in your application; even then, if someone tries to use your application that isn't familiar with this, they just get environment variable not found
or environment variable was not valid unicode: <generic Utf8Error message>
.
Unfortunately, this can't be changed in the stdlib for backcompat purposes since VarError
is an enum, but I think dotenv::var()
should definitely return a more useful error here, which gives it additional utility as well.
The newest tag available in GitHub is 0.14.1, but 0.15 has been released. Please tag releases and push the tags so we can audit changes (especially while the CHANGELOG is not updated (#34))
Hello! I opened a bug report for a utility I was using, which uses this library under the hood. Turns out there's a fix for the bug in question (#24), but it hasn't been released yet. Any chance the lovely maintainers could cut a new release with that fix? ❤️
I have 2 env files, .env
which added to version control and .env.secret
which saves password, is it possible to "source" .env.secret
file in .env
?
for example
# in .env
URL=https://example.com
source .env.secret
# in .env.secret
USERNAME=example
PASSWORD=password
I know dotenv::from_path(".env.secret").ok()
could do this but it would be good to have this feature to make third party cli like "diesel_cli" happy.
Hi there,
The README in https://github.com/dotenv-rs/dotenv/blob/master/README.md#usage states that
dotenv_codegen
provides thedotenv!
macro, which behaves identically toenv!
, but first tries to load a.env
file at compile time.
However, I found v0.15 to only work with a .env file present and not getting any vars from the "real" environment, i.e. according to behaviour, the docs should state
dotenv_codegen
provides the dotenv!
macro, which behaves identically to env!
, but instead tries to load a .env
file at compile time.
Which one is correct, current docs or current implementation?
For my project I need a function that reads ENV file and do not change the current process environment.
I found out dotenv::from_path_iter
is doing exactly what is needed. Unfortunately it is marked as deprecated and it is recommended to use from_path
+ vars
.
The problem is that from_path
updates the environment but I need just to read it, I would modify the env myself.
I could have used Ok(Iter::new(File::open(path).map_err(Error::Io)?))
but Iter
struct is private.
such as .env have pair:a=1 b=2, and .env.prod have pair: b=3;use dotenv::from_filename(".env"),a is 1,b is 2,then use dotenv::from_filename(".env.prod") again,then a is 1, but b is 3
Greetings! Thank you for continuing to maintain this project and creating the repository.
I updated my project to the new version dotenv and saw that iter methods were deprecated. As for me, I found them quite useful in my project, because they allowed me to read dotenv files, preprocess variables and then to decide which of them and how I store in the environment. With deprecating those my only option is to iterate though vars()
(which is basically just env::var()
) and I don't have any way to detect whether those come from the system or from the dotenv file.
Could we consider un-deprecating those methods? Thank you
Much the same issue as here, but I'll put info here for simplicity.
Error is a trait that "[represents] the basic expectations for error values".
It should be easy to implement, the problem is that your implementation of failure::Fail
conflicts because of the cause
function. I was hoping there might be an updated version of failure
that had fixed the issue and you could simply upgrade, but sadly the most recent version1 still has the collision.
1: Version 0.1.5 at time of writing this
------Terminal Display------
(base) [jansel@jansel-pc zzz]$ cargo build
Compiling dotenv v0.10.1
Compiling failure_derive v0.1.5
Compiling serde v1.0.92
Compiling diesel v1.4.2
error[E0659]: `error_chain` is ambiguous (derive helper attribute vs any other name)
--> /home/jansel/.cargo/registry/src/github.com-1ecc6299db9ec823/dotenv-0.10.1/src/lib.rs:23:40
|
23 | #[cfg_attr(not(feature = "backtrace"), error_chain(backtrace = "false"))]
| ^^^^^^^^^^^ ambiguous name
|
note: `error_chain` could refer to the derive helper attribute defined here
--> /home/jansel/.cargo/registry/src/github.com-1ecc6299db9ec823/dotenv-0.10.1/src/lib.rs:22:17
|
22 | #[derive(Debug, error_chain)]
| ^^^^^^^^^^^
note: `error_chain` could also refer to the derive macro imported here
--> /home/jansel/.cargo/registry/src/github.com-1ecc6299db9ec823/dotenv-0.10.1/src/lib.rs:10:1
|
10 | #[macro_use]
| ^^^^^^^^^^^^
error: aborting due to previous error
For more information about this error, try `rustc --explain E0659`.
error: Could not compile `dotenv`.
warning: build failed, waiting for other jobs to finish...
error: build failed
---My dependencies---
actix = "0.8"
actix-rt = "0.2"
actix-web = "1.0.0"
env_logger = "0.6"
openssl = { version="0.10" }
mime = "0.3"
postgres = "0.15"
juniper = "0.12"
diesel = { version = "1.4", features = ["postgres"] }
diesel_codegen = { version = "0.16.0", features = ["postgres"] }
dotenv = "0.14.1"
Consider following .env
file
Foo=Bar Baz
Unfortunately, it cannot get parsed:
thread 'main' panicked at 'called
Result::unwrap()
on anErr
value: LineParse("Bar Baz", 4)', src\main.rs:18:5
One thing this crate was missing before, and is still missing, is the ability to load multiple cascading .env files.
For example, if I have the following in project/.env
:
X=1
Y=2
And the following in project/subdir/.env
:
Y=5
It would be ideal if running dotenv::dotenv()
in project/subdir/
would load
X=1
Y=5
I think one of the hardest parts of this is the API design, though, especially with specifying manual filenames (or directory names for cascading).
If you'd be willing to support this, I would recommend iterating on solutions before committing to 1.0.
I've used dotenv packages in many languages, but this time I got quite confused.
Reason:
A=\.
B="\."
C='\.'
Only C
works. If A
or B
are present, the file fails to load.
Since dotenv.ok()
silence the error, it's quite hard to detect. I guess it should not fail if the file is absent, so we could .expect()
it and be more confident
Is there any possible way to use .env variables inside shell?
.env file:
export REDIS_ADDRESS=localhost:6379
MEANING_OF_LIFE=4
For example using Windows: $env:MEANING_OF_LIFE after using binary and does it work cross platform?
env::home_dir has been deprecated since 1.29.0
Will create a PR to address later.
I'm facing a problem trying to build a project that uses this this crate.
I'm running inside the docker rust:1.44.0.
I have installed the nightly:
rustup toolchain install nightly
info: syncing channel updates for 'nightly-x86_64-unknown-linux-gnu'
info: latest update on 2020-06-12, rust version 1.46.0-nightly (a37c32e2d 2020-06-11)
info: downloading component 'cargo'
5.0 MiB / 5.0 MiB (100 %) 1.5 MiB/s in 2s ETA: 0s
info: downloading component 'rust-std'
15.9 MiB / 15.9 MiB (100 %) 15.0 MiB/s in 1s ETA: 0s
info: downloading component 'rustc'
47.3 MiB / 47.3 MiB (100 %) 10.9 MiB/s in 5s ETA: 0s
info: installing component 'cargo'
info: installing component 'rust-std'
15.9 MiB / 15.9 MiB (100 %) 9.1 MiB/s in 1s ETA: 0s
info: installing component 'rustc'
47.3 MiB / 47.3 MiB (100 %) 9.9 MiB/s in 4s ETA: 0s
nightly-x86_64-unknown-linux-gnu installed - rustc 1.46.0-nightly (a37c32e2d 2020-06-11)
info: checking for self-updates
Now it gives me:
cargo +nightly test
error: failed to download `dotenv v0.15.0`
Caused by:
unable to get packages from source
Caused by:
failed to parse manifest at `/usr/local/cargo/registry/src/github.com-1ecc6299db9ec823/dotenv-0.15.0/Cargo.toml`
Caused by:
readme file with name '../README.md' was not found
Hey guys, what is the current status of this crate? There hasn't been a release to crates.io for 9 months. Are there any blockers for this? If you feel you don't have time/motivation to maintain this project, I'd suggest sharing the rights to push/publish the crate to some contributor
cc @ZoeyR , @purpliminal, @sgrif
If I have a string variable in a .env file like this, then it won't find it and will just ignore it:
PORT=5000
NICE_NAME=My Service
But if I add quotes to the string, then everything is fine:
PORT=5000
NICE_NAME="My Service"
I understand the rationale, but I think it would be better to display an error / warning message, instead of silently dropping the offending variable.
More of a help question.
Is there any way to get only the key, values in the .env file? right now, in the examples one has to go over all std env vars. which is not great I suppose.
The only way I see is to keep a track of the list of keys in .env separately in a Vector in the code
Hi 👋🏻,
I'm working with a project using a Cargo workspace and am trying to set it up to use a .env
file for each project in the workspace instead of a single .env
file at the root of the repository.
Unfortunately, the dotenv_codegen
macro is failing when the .env
file is not at the root of the workspace.
This seems at odds with the dotenv
code and documentation, which says the library "will load environment variables from a file named .env in the current directory or any of its parents".
I started a new project with a workspace holding a single project whose only job is to print the environment variable embedded with the dotenv_codegen
macro and was able to reproduce the issue, so I'm fairly certain this is a problem with the macro and not with anything in my existing project.
The dotenv!
macro should have more using friendly error messages. In particular it should indicate where the parsing error was in the .env
file.
What is the purpose of dotenv::var
and dotenv::vars
and how do they compare to their std::env equivalents
I recommend following https://keepachangelog.com/en/1.0.0/
For example, I can't easily tell the differences between 0.13 (my current version) and 0.14.1 (the current). I know that there were some issues with the ownership of the crate and that the detailed changes from 0.13 to 0.14 might be difficult, but the ownership change itself would be reasonable to document.
An issue was opened on the rustc repo about dotenv-codegen
hanging forever: rust-lang/rust#62167
I haven't investigated, but I'd guess it's the dotenv
proc macro that hangs
with dotenv = "0.15.0"
#[derive(Deserialize)]
pub struct Config {
pub var: u32
}
works, but
#[derive(Deserialize)]
pub struct Config {
#[serde(flatten)]
pub sub: Sub,
}
#[derive(Deserialize)]
pub struct Sub {
pub var: u32
}
gives an error at runtime :
Error: Custom("invalid type: string \"0\", expected u32")
Coming from https://github.com/bkeepers/dotenv, is there a way to use these files too: https://github.com/bkeepers/dotenv#what-other-env-files-can-i-use?
Hierarchy Priority | Filename | Environment | Should I .gitignoreit? | Notes |
---|---|---|---|---|
1st (highest) | .env.development.local | Development | Yes! | Local overrides of environment-specific settings. |
1st | .env.test.local | Test | Yes! | Local overrides of environment-specific settings. |
1st | .env.production.local | Production | Yes! | Local overrides of environment-specific settings. |
2nd | .env.local | Wherever the file is | Definitely. | Local overrides. This file is loaded for all environments except test. |
3rd | .env.development | Development | No. | Shared environment-specific settings |
3rd | .env.test | Test | No. | Shared environment-specific settings |
3rd | .env.production | Production | No. | Shared environment-specific settings |
Last | .env | All Environments | Depends (See below) | The Original® |
Yooooo!
I wrote a framework for comparing dotenv implementations: https://github.com/casey/dotenv-compare
Right now it only compares a few implementations, doesn't have a lot of test cases, and it doesn't deal gracefully with implementations crashing, so it's more of a proof-of-concept than anything else.
At the very least, I'd like to (hopefully with help!) add more test cases to it, and use it to make sure that dotenv-rs is in conformance with the ruby implementation. (Assuming that is a goal for dotenv-rs!)
Once it has a comprehensive set of test cases that exercise all aspects of popular implementations, I think it would be useful to think about creating a standard for .env files, hopefully with support from other implementations. Ideally, new implementations could be written with the aid of a formal grammar, and tested against a set of test cases, instead of using the Ruby implementation as an ad-hoc standard.
Do you think this is something that could live in the dotenv-rs organization?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.