cargo icon indicating copy to clipboard operation
cargo copied to clipboard

Add a `--ignore-local-config` flag for ignoring local `.cargo/config.toml` files

Open phil-opp opened this issue 5 years ago • 16 comments

Describe the problem you are trying to solve

Cargo configuration files (.cargo/config or .cargo/config.toml) provide powerful options for changing how a project is compiled. Since they are based on file system hierarchy and the current working directory where cargo is invoked, they automatically apply to all subdirectories. This property is useful in many situations, e.g. when running the cargo command from the src folder of a project, but it can lead to problems in some other cases.

One potential source of problems is the --manifest-path argument of cargo. This argument allows to run a cargo command on a crate in a different directory. Since the current working directory is not changed for this, the configuration of the folder where the cargo command is run from is applied, not the config from the referenced project. This might break the compilation, e.g. when a default target or special rustflags are set in a local config file.

A second source of problems are programs that invoke cargo commands, for example some cargo related command line applications. Depending on the directory they are run in, they might behave completely differently because all project-local configuration is applied. This was also a problem for the cargo install subcommand, until the behavior was changed to only load ~/cargo/.config for cargo install.

Describe the solution you'd like

To solve the mentioned problems, an --ignore-local-config or --isolated flag for cargo would be very useful. Similar to the behavior of cargo install, cargo invocations with this flag would only load the global configuration from ~/cargo/.config, but not any other local configuration files from the current working directory. This way, cargo commands can be made independent of the current working directory if desired.

Notes

I'm happy to create a pull request for this, but I wanted to ask for opinions first. I think the Config::reload_rooted_at method would make the implementation quite simple. Of course we could add such a flag as an unstable flag first.

phil-opp avatar Aug 23 '20 10:08 phil-opp

I also would find this useful, I think. My situation is thus: I have a "build just this package" build, and a "build this package as part of a bigger project" build. For the former, setting some linker arguments in .cargo/config is great, but then for the second build, I don't want those settings, but different ones.

steveklabnik avatar Oct 01 '20 14:10 steveklabnik

I used to use --manifest-path since it allowed to mount my code as read-only in a VM, while building from a writable directory. However the fact that .cargo/config.toml isn't respected means I can't do that anymore. A flag like --use-config=<path> or something might be useful in this case (or a flag to pick the config from the root of the project, even if it's not the current directory)

jgouly avatar Dec 10 '20 14:12 jgouly

@jgouly Check out https://internals.rust-lang.org/t/proposal-move-some-cargo-config-settings-to-cargo-toml/13336. The proposal takes a different way than your suggestion, but I think it should help in your use case as well. The good news is that the Cargo team has signaled their approval of this proposal, so we just need to implement it.

phil-opp avatar Dec 10 '20 15:12 phil-opp

--ignore-local-config (which ignores both ~/.cargo/config.toml and .cargo/config.toml) would be useful when trying to create a pristine Cargo.lock.

Atm there does not seem to exist a way to ignore [patch] sections in these files so that the resulting Cargo.lock works only in the local environment.

ensc avatar Jan 31 '25 11:01 ensc

This appears to be the same as #7621 and I'm going to close in favor of that. If there is a reason for us to re-evaluate, let us know!

epage avatar Nov 06 '25 21:11 epage

#7621 is about ignoring parent config files. This issue is about ignoring all config files (except for the one on the HOME dir).

One motivation for this issue is builds with --manifest-path, which read the config from the current working dir, not the crate dir. If we want to avoid side effects of unrelated config files, we need to ignore the config file in the working dir too, not just in parent dirs.

phil-opp avatar Nov 06 '25 21:11 phil-opp

https://github.com/rust-lang/cargo/issues/7621 is about ignoring parent config files. This issue is about ignoring all config files (except for the one on the HOME dir).

Could you help me understand the distinction? From the way I read it, there are only two types of config files

  • from parent directories
  • from HOME

So if you ignore only parent config files, that is the same as ignoring all config files except from HOME.

epage avatar Nov 06 '25 21:11 epage

Maybe I misunderstood #7621 and linked #7620. I thought that it proposed to still apply the config file of the current working dir. So if the project lives at /a/b/c, that a/b/c/.cargo/ config.toml is still applied. Just not the ones in a/b and a.

phil-opp avatar Nov 07 '25 07:11 phil-opp

Wow, that requires some digging to clarify that.

epage avatar Nov 07 '25 15:11 epage

From https://github.com/rust-lang/cargo/issues/7621#issuecomment-1791812280

In some tools, I've seen them have an --isolated flag that causes it to not implicitly load any config, leaving it only to the --config flag / env variables.

epage avatar Nov 07 '25 15:11 epage

--config is the only way you truly know something is for a specific command invocation.

That still leaves

  • local config
  • user config
  • (requested) global config (#9441)
  • env variables: these could be for a specific invocation or be like user config and generically applied

Depending on the use case, I could see needing to control various levels of this. I wonder if we could find a way to solve #7621 that would also cover the local config. The other config files might be ok to be grouped together in --isolated. Env variables would likely require the caller to enumerate all env variables and then remove any of the form CARGO_*.

epage avatar Nov 07 '25 16:11 epage

Thanks for reopening and sorry for the confusion!

In some tools, I've seen them have an --isolated flag that causes it to not implicitly load any config, leaving it only to the --config flag / env variables.

Yes, that's basically what this issue is proposing. I thought that maybe we want to keep applying the config file from the HOME directory since it typically contains global stuff such as http proxy config. But I don't have a strong opinion about that.

edit: I updated the issue description to also mention --isolated as a potential flag name

phil-opp avatar Nov 07 '25 16:11 phil-opp

I think https://github.com/rust-lang/cargo/issues/12738 is also related in a way. Once we can move all project-specific configuration from .cargo/config to Cargo.toml, there will be less need for such an --isolated flag.

phil-opp avatar Nov 07 '25 16:11 phil-opp

#7621 is about ignoring parent config files. This issue is about ignoring all config files (except for the one on the HOME dir).

I wonder why $CARGO_HOME/config.toml is special here. If there were a --isolated flag them people can always pass --config $CARGO_HOME/config.toml to get them back, right?

weihanglo avatar Nov 30 '25 21:11 weihanglo

That part was motivated by https://github.com/rust-lang/cargo/pull/6026. I thought that settings that are applied even to a cargo install are probably not something you want to disable (e.g. network-specific proxy config). I don't feel strongly about this though, I'm also fine with ignoring all config files (and let users opt-in again if desired).

phil-opp avatar Nov 30 '25 21:11 phil-opp

-Zconfig-include (https://github.com/rust-lang/cargo/issues/7723) could be a way to work around, by not putting any configuration files in any parent directories. Though that is not a complete "isolated" solution (see https://github.com/rust-lang/cargo/pull/16284#discussion_r2550631799 for more use examples).

We could probably have a top-level probing key in Cargo configuration:

  • Cargo stops config probing when reading probing=false.
  • One can set a config probing boundary at any directory level. For example, a config at workspace root, or even a parent directory in a larger meta build system.
  • If $CARGO_HOME/config.toml is needed, setting an extra include loading it should be sufficient.
  • We could even pass --config 'probing=false' through CLI, so Cargo stops the entire probing at config CLI level (config CLI has the highest precedence), so that we completely isolate configurations.

Though probing might not be a good config name.

weihanglo avatar Nov 30 '25 21:11 weihanglo