Skip to content

feat: --config-file should take precedence over environment variables #436

@joshrotenberg

Description

@joshrotenberg

Problem

When --config-file is explicitly specified, environment variables still take precedence over the config file values. This makes it difficult to achieve true configuration isolation for testing and creates surprising behavior.

Current Behavior (Problematic)

Priority: Env vars > --config-file > Default config

If you have:

  • REDIS_CLOUD_API_KEY=production-key in environment
  • --config-file /tmp/test.toml with api_key = "test-key"

Result: Uses production-key (from env) instead of test-key (from explicit config)

Expected Behavior

Priority: --config-file (explicit) > Env vars > Default config

When --config-file is explicitly provided, it should take precedence over environment variables.

Rationale

  1. Principle of Least Surprise: Explicit flags should override implicit environment
  2. Testing Isolation: Makes it possible to test with isolated configs without unsetting env vars
  3. Explicit Wins: CLI best practice - explicit arguments > environment > defaults
  4. Consistency: Similar to how tools like kubectl --kubeconfig or git --config work

Proposed Solution

Option 1: Auto-disable env vars when --config-file is used (Recommended)

When --config-file is specified, ignore environment variable overrides for credential lookups.

Pros:

  • Simple and intuitive
  • Complete isolation by default
  • No additional flags needed

Cons:

  • Changes existing behavior (breaking change)
  • Can't selectively override single credentials from env

Option 2: Add --ignore-env or --strict-config flag

Add a flag to explicitly disable environment variable lookups.

redisctl --config-file /tmp/test.toml --ignore-env cloud subscription list

Pros:

  • Opt-in, not breaking
  • Explicit control

Cons:

  • More flags to remember
  • Verbose

Use Cases

Testing (Primary driver)

// Currently fails because env vars override test config
let test_config = create_test_config_with_mock_server();
Command::cargo_bin("redisctl")
    .arg("--config-file").arg(test_config)
    .arg("cloud").arg("subscription").arg("list")
    .assert()
    .success(); // ❌ Fails - uses real credentials from env

Temporary config override

# Want to test against staging without modifying main config
redisctl --config-file staging.toml cloud subscription list
# ❌ Currently uses production creds from env vars anyway

Recommendation

Implement Option 1 (auto-disable env vars when --config-file specified) as the new behavior in next major version. This provides the most intuitive behavior and is consistent with other CLI tools.

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions