Skip to content

non-mergeable list from env shouldn't take precendence over config-cli #16208

@weihanglo

Description

@weihanglo

Problem

Reproducible example

#[cargo_test]
fn nonmergeable_lists_precedence() {
    let foo_path = paths::root().join("foo/.cargo/config.toml");
    write_config_at(
        &foo_path,
        "\
[a]
b = ['chromium', 'config']
",
    );

    // config-cli takes precedence
    let config_arg = "doc.browser=['firefox', 'cli']";
    let gctx = GlobalContextBuilder::new()
        .cwd("foo")
        .config_arg(config_arg)
        .build();
    let provider = gctx
        .get::<Option<context::PathAndArgs>>("doc.browser")
        .unwrap()
        .unwrap();
    assert_eq!(provider.path.raw_value(), "firefox");
    assert_eq!(provider.args, ["cli"]);

    // config-cli should takes precedence, but env wins
    let gctx = GlobalContextBuilder::new()
        .cwd("foo")
        .env("CARGO_DOC_BROWSER", "servo env")
        .config_arg(config_arg)
        .build();
    let provider = gctx
        .get::<Option<context::PathAndArgs>>("doc.browser")
        .unwrap()
        .unwrap();
    assert_eq!(provider.path.raw_value(), "servo");
    assert_eq!(provider.args, ["env"]);
}

Possible Solution(s)

Probably something like this in get_env_list()?

+        let def = Definition::Environment(key.as_env_key().to_string());
+
         if is_nonmergeable_list(&key) {
-            output.clear();
+            debug_assert!(
+                output
+                    .windows(2)
+                    .all(|cvs| cvs[0].definition() == cvs[1].definition()),
+                "since the output is a non-mergeable list, it must have only one definition: {output:?}",
+            );
+
+            // We prefer to env config if no higher definition found (i.e, no `--config` CLI)
+            // Otherwise we should stop and use that instead.
+            if output.iter().all(|cv| &def >= cv.definition()) {
+                output.clear();
+            } else {
+                return Ok(());
+            }
         }

Version

latest master: 0f14d9d

I haven't checked if it was buggy since #15066 or it is a recent regression.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-config-cliArea: --config CLI optionA-configurationArea: cargo config files and env varsC-bugCategory: bugS-triageStatus: This issue is waiting on initial triage.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions