rust-lang / cargo

The Rust package manager
https://doc.rust-lang.org/cargo
Apache License 2.0
12.25k stars 2.31k forks source link

Add option to set environment variables only for being run process #4505

Open mikhail-m1 opened 6 years ago

mikhail-m1 commented 6 years ago

It'll be great to add -e NAME=value(for example) flag to cargo run for set environment variables. Setting environment variables is platform/shell dependent and required additional steps from user.

Simplest use case is RUSTLOG, of cause its possible to add filters by main module name, but what about dependent modules? May be it will be useful for set some LD* fields which may break cargo itself.

EDIT (ehuss): and the ability to unset environment variables. See #7790.

alexkreidler commented 4 years ago

I strongly support this feature as a way to improve developer productivity.

If you want developers to use the cargo run command, which usually only happens when actively making changes, it makes no sense to restrict the developer from creating a realistic dev environment, complete with env vars like RUST_LOG=debug.

Otherwise, it's a two-step process: recompile and then run your CLI command.

I still don't fully understand the reasoning behind not merging #4557, besides a common hesitation to avoid feature creep. But this seems like a core feature, in the vein of allowing arguments to be passed, or stdin to be passed along (which was merged in #268).

I hope someone on the team can reconsider this issue and maybe merge the PR which addresses it. Thanks!

snobb commented 1 year ago

Just curious, how the -e option makes it more useful than: FOO=bar cargo run?

eg. below passes if I set env variable (and fails otherwise):

mkdir envtest && cd $_
cargo init
echo '#[test]
fn target() {
    assert_eq!(env!("FOO"), "bar");
}' > src/lib.rs
FOO=bar cargo test >/dev/null 2>&1 && echo OK || echo FAIL      # prints OK
cargo test >/dev/null 2>&1 && echo OK || echo FAIL              # prints FAIL
mikhail-m1 commented 1 year ago

Just curious, how the -e option makes it more useful than: FOO=bar cargo run?

Without -e the environment variable is passed to cargo and to the target process, and sometimes you need to pass it only to the target process, for example LD_PRELOAD.

ollyde commented 1 year ago

I'm loading dev with the following auto-reloading command and environmental var at the beginning for now.

env=dev npx nodemon --watch './src/**/*' -e rs --exec cargo run

Seems to work with

use std::env;

fn get_env() -> String {
    let env = match env::var("env") {
        Ok(val) => val,
        Err(_e) => "dev".to_string(),
    };
    return env;
}

If you're using VSC you can also set a launch script and run from the debugger which is handy for restarts as well.

{
    "version": "0.2.0",
    "configurations": [
        {
            "type": "lldb",
            "request": "launch",
            "name": "Debug Rust",
            "cargo": {
                "args": ["build", "--manifest-path", "${fileDirname}/../Cargo.toml"]
            },
            "env": {
                // This would be "ENV" instead of "env" in the code.
                "ENV": "dev"
            }
        }
    ]
}
rami3l commented 2 months ago

@epage This feature would be interesting in Rustup development. Similar to https://github.com/rust-lang/cargo/issues/4505#issuecomment-634316109, we essentially need to pass an env var to the actual executable (rustup-init in this case) but not to cargo.

To test if a rustup command (e.g. rustup --version) still works after changes, we currently use a two-step approach:

cargo build
RUSTUP_FORCE_ARG0=rustup ./target/debug/rustup-init --version

The ./target/debug/rustup-init part is... a bit against the point of cargo run, and we cannot pass RUSTUP_FORCE_ARG0 to cargo since here cargo is a rustup shim...

OTOH cargo run --env RUSTUP_FORCE_ARG0=rustup -- --version would be perfect.

This is the workaround that I use for now in fish:

begin
    set -l CARGO (rustup which cargo)
    RUSTUP_FORCE_ARG0=rustup $CARGO run -- --version
end

I understand that this might be a niche requirement though, just doing some feedback in case you're interested :]

epage commented 2 months ago

iirc rustc is gaining a CLI for controlling the build environment variables. It might be interesting to see what they have (when stabilized) and mirror that.

The question would be whether we should expose rustc's CLI in cargo build commands. At that point, there would be conflicts. However, I would lean towards saying that cargo rustc should be the only command that should allow CLI access to rustc's env CLI as that is meant to give more direct control and instead the env config table is likely a better place for setting things that should be forward to the build (which includes --config) as that would be encouraging more repeatability between projects.