Skip to content

Tracking: settings.toml and its stability guarantees #4944

Open
1 of 3 issues completed
Open

Description

@rami3l

I am bringing this up because of @djc's point that introducing too many environment variables for configuration might be too noisy: #4869 (comment)

It seems that, following cargo's convention, a lot of cargo's config should have env var counterparts. Should rustup move more or less towards that direction?

Also there has been a previous topic regarding Nix-generated settings.toml in #4167, the question is whether we should stabilize at least a part of this config.

For now I have this on my machine:

version = "12"
default_toolchain = "stable-aarch64-apple-darwin"
profile = "default"
auto_install = "disable"

[overrides]

... but it's not entirely clear if this config should change much (and thus can be backed up/generated by a dotfile manager like chezmoi/Nix) and if so under what circumstances. Using rustup default to change the settings might look surprising because one may expect that only rustup set can change it.

Now that we have state.toml maybe we can move some values over there.

Activity

  1. changed the title [-]Reconsider the stance on `settings.toml` and its stability guarantees[/-] [+]Tracking: `settings.toml` and its stability guarantees[/+] on Jul 7, 2026
  2. djc commented on Jul 8, 2026

    @djc
    Contributor

    It seems that, following cargo's convention, a lot of cargo's config should have env var counterparts. Should rustup move more or less towards that direction?

    Can you be more concrete about what you mean with this?

    Also there has been a previous topic regarding Nix-generated settings.toml in #4167, the question is whether we should stabilize at least a part of this config.

    I'd be okay with documenting the contents of config.toml, noting the caveat that newer versions would change things.

    ... but it's not entirely clear if this config should change much (and thus can be backed up/generated by a dotfile manager like chezmoi/Nix) and if so under what circumstances. Using rustup default to change the settings might look surprising because one may expect that only rustup set can change it.

    version is kind of meta, but it feels to me like all of default_toolchain, profile and auto_install are more "configuration" then "state", in the sense that they're only ever changed by the user (rather than changed by rustup "behind the scenes"). IMO that is somewhat independent from if they're set only via the CLI or directly with an editor.

  3. rami3l commented on Jul 8, 2026

    @rami3l
    MemberAuthor

    It seems that, following cargo's convention, a lot of cargo's config should have env var counterparts. Should rustup move more or less towards that direction?

    Can you be more concrete about what you mean with this?

    @djc A lot of cargo configurations can be changed by either env var or config.toml. As stated in the docs:

    For example the target.x86_64-unknown-linux-gnu.runner key can also be defined by the CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUNNER environment variable.

    If we are pursuing consistency within the Rust tool suite, this might be a direction worth investigating.

  4. djc commented on Jul 8, 2026

    @djc
    Contributor

    IMO any work here starts with gathering up all the environment variables we currently look for, all the configuration we store, and then coming up with some heuristics for what is a good path forward for this stuff.

    I'd be hesitant to follow Cargo on this without a better understanding of their rationale for this design. It feels like just adding more complexity without anyone really asking for it?

  5. rami3l commented on Jul 8, 2026

    @rami3l
    MemberAuthor

    IMO any work here starts with gathering up all the environment variables we currently look for, all the configuration we store, and then coming up with some heuristics for what is a good path forward for this stuff.

    @djc I 100% agree with this point. I would like to stress that currently we have rustup set, rustup default and rustup override that may change the config which is basically used to collect everything that the past versions felt like persisting:

    rustup/src/settings.rs

    Lines 81 to 99 in 06111c1

    #[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
    pub struct Settings {
    pub version: MetadataVersion,
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(alias = "default_host_triple")]
    pub default_host_tuple: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub default_toolchain: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub profile: Option<Profile>,
    #[serde(default)]
    pub overrides: BTreeMap<String, String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub pgp_keys: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub auto_self_update: Option<SelfUpdateMode>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub auto_install: Option<AutoInstallMode>,
    }

    What I am thinking about here is the possibility to have a new design that reorganizes everything that you have mentioned into the new rustup config subcommand as suggested in #4919 (comment), this way we can probably achieve more logical coherence in that regard, say rustup default would be an alias that sets something with rustup config set.

    I'd be hesitant to follow Cargo on this without a better understanding of their rationale for this design. It feels like just adding more complexity without anyone really asking for it?

    As I read it, the rationale here is to have the flexibility of both one-off and persistent configurations.

  6. djc commented on Jul 8, 2026

    @djc
    Contributor

    As I read it, the rationale here is to have the flexibility of both one-off and persistent configurations.

    Sure, but having an environment variable to set the default_toolchain doesn't make sense since we already have RUSTUP_TOOLCHAIN to override that, anyway.

    I'd rather limit adding more surface based on what people actually ask for.

  7. rami3l commented on Jul 8, 2026

    @rami3l
    MemberAuthor

    As I read it, the rationale here is to have the flexibility of both one-off and persistent configurations.

    Sure, but having an environment variable to set the default_toolchain doesn't make sense since we already have RUSTUP_TOOLCHAIN to override that, anyway.

    I'd rather limit adding more surface based on what people actually ask for.

    @djc A tiny correction: the default toolchain is different from the active toolchain, but I can totally see your point regarding minimizing our surface of interaction.

    Since our ultimate goal should be to clean up this mess WRT different configuration methods (env var versus settings.toml), the next questions would be:

    • Should we ban the addition of new env vars for config of new features (so that settings.toml should be prioritized) unless proven necessary?
    • Should we make the format of settings.toml a part of our stability guarantees (at the risk of possibly enlarging our public interface)?

    As for a complete summary of all configuration options that has been introduced thus far, I believe it should come up naturally when working on #4919.

  8. djc commented on Jul 8, 2026

    @djc
    Contributor
    • Should we ban the addition of new env vars for config of new features unless proven necessary (so that settings.toml should be prioritized)?

    I think settings.toml is clearly better for configuration that is likely to be persistent (user picks once, sets forever), and environment variables are clearly better for things that are likely to be session-specific or potentially because they need to be more accessible to automation.

    • Should we make the format of settings.toml a part of our stability guarantees (at the risk of possibly enlarging our public interface)?

    I think that's reasonable.

  9. rami3l commented on Jul 8, 2026

    @rami3l
    MemberAuthor

    version is kind of meta, but it feels to me like all of default_toolchain, profile and auto_install are more "configuration" then "state", in the sense that they're only ever changed by the user (rather than changed by rustup "behind the scenes").

    @djc Good point. Looking back I think I have a concern about the overlap between default_host_tuple and default_toolchain which might make the whole config not very backup-friendly, but I guess that can go into a separate issue.

  10. ChrisDenton commented on Jul 8, 2026

    @ChrisDenton
    Member

    One thing I think we often do is add experimental options as environment variables. This can admittedly make testing a bit easier but does mean that if it does turn out to be useful we're locked in to supporting it as an environment variable (otherwise we'd break people using it). Maybe we should use an [unstable] section in the settings.toml for such experiments?

  11. rami3l commented on Aug 28, 2026

    @rami3l
    MemberAuthor

    A side note here: looking at https://rust-lang.zulipchat.com/#narrow/channel/490103-t-rustup/topic/rust-toolchain.2Etoml.20init.20command/with/619737924 I have a feeling that [overrides] is also preventing a proper cross-machine backup which might be problematic in certain cases.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions