Skip to content

Proposal: Command-line config #6699

Closed
@ehuss

Description

@ehuss

This is a two-part proposal to make it easier to use Cargo config settings.

  1. Add --config <key>=<value> command-line argument for setting config values for the current command.
  2. Add include key to the config for including other config files.

It is intended that the use of these should be relatively rare and only for advanced use cases.

--config CLI option

The --config command-line option is a global option available to all commands. It sets the given config key to the given value, and takes precedence over all other sources (environment variables and all config files). The argument is parsed as TOML syntax. The --config flag may be specified multiple times, in which case the values are merged in left-to-right order, using the same merging logic that multiple config files use.

Some examples of what it looks like using Bourne shell syntax:

# Most shells will require escaping.
cargo --config http.proxy=\"http://example.com\"# Spaces may be used.
cargo --config "net.git-fetch-with-cli = false"# TOML array example. Single quotes make it easier to read and write.
cargo --config 'build.rustdocflags = ["--html-in-header", "header.html"]'# Example of a complex TOML key.
cargo --config "target.'cfg(all(target_arch = \"arm\", target_os = \"none\"))'.runner = 'my-runner'"# Example of overriding a profile setting.
cargo --config profile.dev.overrides.image.opt-level=3 …

include key

The include key may be used to include other config files. It may be a string for a path to the file, or a TOML array of strings to include multiple files. The paths are relative to the config file where it is defined, or from the current working directory if used from an environment variable or command-line option.

When used in a config file, the include is loaded and merged immediately after the file with the include key has been loaded and fully processed. When used from an environment variable (CARGO_INCLUDE), it is loaded after all config files have been loaded. When used from the command line (--config include=…), it is loaded after the environment variable has been processed. This will require special handling as normally config values replace and shadow previous ones.

include = "config-foo"

In conjunction with --config, this can be a convenient way to specify other config files on the command-line:

cargo --config 'include=".cargo/config-foo"'

Users are allowed to use filenames of the form .cargo/config-*, though users are free to use other filenames outside of the .cargo directory.

Questions and concerns:

  • Restricting the CLI to <key>=<value> may be tricky, because toml-rs does not provide a way to restrict that. It would be easy to restrict to a single value, but would still allow comments, or things like [foo]\nbar=1. I would prefer to be conservative and only allow a restricted syntax and not allow any free-form TOML, but that may be difficult. If that's a concern, should toml-rs be extended to support this case? How should this be handled?
  • Does it make sense for include via env/cli to be relative to CWD? I think that seems natural, but perhaps the workspace root would be another option? Or maybe a limited env var substitution?
  • I'm concerned the real-world use cases may not be strong enough to justify this addition (at least in this form).
  • When an environment variable or command-line option are required to properly use a package, it can make a package more difficult to use. This may encourage overly clever solutions that make using Cargo a less pleasant experience. For example, requiring the --config option to properly compile something would make IDEs and other tools unable to work properly (or require arduous setup).

References:

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-cliArea: Command-line interface, option parsing, etc.A-configurationArea: cargo config files and env vars

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions