-
Notifications
You must be signed in to change notification settings - Fork 2.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Environment variables override cargo --config <filename> in precedence #10992
Comments
Hm, yea, that's a strange intersection. I'm not sure how hard that would be to fix, but would be good to investigate. |
I also realized that there's a related issue. If
Then the behavior I expect is that configs would have precedence in this order:
However, in reality, configs have precedence in this order:
|
The main issue to note here is rust-lang/cargo#10992.
The main issue to note here is rust-lang/cargo#10992.
The main issue to note here is rust-lang/cargo#10992.
From my understanding, the change you referred to might not be the root cause. Either config-include or
You are correct that the behaviour is wrong. The precedence you describe could be more precise. AFAIK the flow looks like,
For instance, when one runs
It would look like the followings after cli-args merge before env merge:
I feel like the fix would be tricky. We may want to construct a Click to expand this cargo test case exercising the behaviour aforementioned.#[cargo_test]
fn merge_primitives_for_multiple_cli_occurences() {
let config_path0 = ".cargo/file0.toml";
write_config_at(config_path0, "k = 'file0'");
let config_path1 = ".cargo/file1.toml";
write_config_at(config_path1, "k = 'file1'");
// k=env0
let config = ConfigBuilder::new().env("CARGO_K", "env0").build();
assert_eq!(config.get::<String>("k").unwrap(), "env0");
// k=env0
// --config k='cli0'
// --config k='cli1'
let config = ConfigBuilder::new()
.env("CARGO_K", "env0")
.config_arg("k='cli0'")
.config_arg("k='cli1'")
.build();
assert_eq!(config.get::<String>("k").unwrap(), "cli1");
// Env has a lower priority when comparing with file from CLI arg.
//
// k=env0
// --config k='cli0'
// --config k='cli1'
// --config .cargo/file0.toml
let config = ConfigBuilder::new()
.env("CARGO_K", "env0")
.config_arg("k='cli0'")
.config_arg("k='cli1'")
.config_arg(config_path0)
.build();
assert_eq!(config.get::<String>("k").unwrap(), "file0");
// k=env0
// --config k='cli0'
// --config k='cli1'
// --config .cargo/file0.toml
// --config k='cli2'
let config = ConfigBuilder::new()
.env("CARGO_K", "env0")
.config_arg("k='cli0'")
.config_arg("k='cli1'")
.config_arg(config_path0)
.config_arg("k='cli2'")
.build();
assert_eq!(config.get::<String>("k").unwrap(), "cli2");
// k=env0
// --config k='cli0'
// --config k='cli1'
// --config .cargo/file0.toml
// --config k='cli2'
// --config .cargo/file1.toml
let config = ConfigBuilder::new()
.env("CARGO_K", "env0")
.config_arg("k='cli0'")
.config_arg("k='cli1'")
.config_arg(config_path0)
.config_arg("k='cli2'")
.config_arg(config_path1)
.build();
assert_eq!(config.get::<String>("k").unwrap(), "file1");
} |
Problem
If both an environment variable and
cargo --config <filename>
are specified at the same time, the environment variable overrides the file passed in over the CLI. This is counter-intuitive and also the documentation at https://doc.rust-lang.org/cargo/reference/config.html#command-line-overrides is unclear about this:Steps
Create
.cargo/foo.toml
:Then, run:
Notice that the build happens in "from-env" rather than the expected "from-too-toml".
Possible Solution(s)
I think the behavior should be changed so that config files passed in over
--config
come first and environment variables come later.(Unlike #10991, this I think is straight-up incorrect and should be fixed.)
Notes
I'm guessing this is a regression from #10755 and specifically this change, though I could be wrong. cc @jonhoo, @ehuss
Version
The text was updated successfully, but these errors were encountered: