Skip to content

Commit 1db9dc9

Browse files
authored
Merge pull request #2244 from rbtcollins/fallback-settings
fallback-settings file
2 parents 6d00230 + f6315b4 commit 1db9dc9

File tree

7 files changed

+94
-4
lines changed

7 files changed

+94
-4
lines changed

Cargo.lock

Lines changed: 15 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ remove_dir_all = "0.5.1"
4242
same-file = "1"
4343
scopeguard = "1"
4444
semver = "0.9"
45+
serde = { version = "1.0", features = ["derive"] }
4546
sha2 = "0.8"
4647
strsim = "0.9.1"
4748
tar = "0.4.26"

README.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ And it runs on all platforms Rust supports, including Windows.
3131
* [Working with custom toolchains](#working-with-custom-toolchains-and-local-builds)
3232
* [Working with network proxies](#working-with-network-proxies)
3333
* [Examples](#examples)
34+
* [Configuration files](#configuration-files)
3435
* [Environment variables](#environment-variables)
3536
* [Other installation methods](#other-installation-methods)
3637
* [Security](#security)
@@ -639,6 +640,17 @@ Command | Description
639640
`rustup toolchain help` | Show the `help` page for a subcommand (like `toolchain`)
640641
`rustup man cargo` | \(*Unix only*\) View the man page for a given command (like `cargo`)
641642

643+
## Configuration files
644+
645+
Rustup has a settings file in [TOML](https://github.com/toml-lang/toml) format
646+
at `${RUSTUP_HOME}/settings.toml`. The schema for this file is not part of the
647+
public interface for rustup - the rustup CLI should be used to query and set
648+
settings.
649+
650+
On Unix operating systems a fallback settings file is consulted for some
651+
settings. This fallback file is located at `/etc/rustup/settings.toml` and
652+
currently can define only `default_toolchain`.
653+
642654
## Environment variables
643655

644656

src/config.rs

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use pgp::{Deserializable, SignedPublicKey};
1111

1212
use crate::dist::{dist, temp};
1313
use crate::errors::*;
14+
use crate::fallback_settings::FallbackSettings;
1415
use crate::notifications::*;
1516
use crate::settings::{Settings, SettingsFile, DEFAULT_METADATA_VERSION};
1617
use crate::toolchain::{Toolchain, UpdateStatus};
@@ -108,10 +109,13 @@ impl Display for PgpPublicKey {
108109
}
109110
}
110111

112+
pub const UNIX_FALLBACK_SETTINGS: &str = "/etc/rustup/settings.toml";
113+
111114
pub struct Cfg {
112115
pub profile_override: Option<dist::Profile>,
113116
pub rustup_dir: PathBuf,
114117
pub settings_file: SettingsFile,
118+
pub fallback_settings: Option<FallbackSettings>,
115119
pub toolchains_dir: PathBuf,
116120
pub update_hash_dir: PathBuf,
117121
pub download_dir: PathBuf,
@@ -133,6 +137,13 @@ impl Cfg {
133137

134138
let settings_file = SettingsFile::new(rustup_dir.join("settings.toml"));
135139

140+
// Centralised file for multi-user systems to provide admin/distributor set initial values.
141+
let fallback_settings = if cfg!(not(windows)) {
142+
FallbackSettings::new(PathBuf::from(UNIX_FALLBACK_SETTINGS))?
143+
} else {
144+
None
145+
};
146+
136147
let toolchains_dir = rustup_dir.join("toolchains");
137148
let update_hash_dir = rustup_dir.join("update-hashes");
138149
let download_dir = rustup_dir.join("downloads");
@@ -191,6 +202,7 @@ impl Cfg {
191202
profile_override: None,
192203
rustup_dir,
193204
settings_file,
205+
fallback_settings,
194206
toolchains_dir,
195207
update_hash_dir,
196208
download_dir,
@@ -362,9 +374,7 @@ impl Cfg {
362374
}
363375

364376
pub fn find_default(&self) -> Result<Option<Toolchain<'_>>> {
365-
let opt_name = self
366-
.settings_file
367-
.with(|s| Ok(s.default_toolchain.clone()))?;
377+
let opt_name = self.get_default()?;
368378

369379
if let Some(name) = opt_name {
370380
let toolchain = Toolchain::from(self, &name)?;
@@ -510,7 +520,14 @@ impl Cfg {
510520
}
511521

512522
pub fn get_default(&self) -> Result<Option<String>> {
513-
self.settings_file.with(|s| Ok(s.default_toolchain.clone()))
523+
let user_opt = self.settings_file.with(|s| Ok(s.default_toolchain.clone()));
524+
if let Some(fallback_settings) = &self.fallback_settings {
525+
match user_opt {
526+
Err(_) | Ok(None) => return Ok(fallback_settings.default_toolchain.clone()),
527+
_ => {}
528+
};
529+
};
530+
user_opt
514531
}
515532

516533
pub fn list_toolchains(&self) -> Result<Vec<String>> {

src/errors.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,9 @@ error_chain! {
347347
display("component {} was automatically added because it is required for toolchain '{}'",
348348
c, t)
349349
}
350+
ParsingFallbackSettings(e: toml::de::Error) {
351+
description("error parsing settings")
352+
}
350353
ParsingSettings(e: toml::de::Error) {
351354
description("error parsing settings")
352355
}

src/fallback_settings.rs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
use crate::errors::*;
2+
use crate::utils::utils;
3+
use serde::Deserialize;
4+
use std::error::Error;
5+
use std::io;
6+
use std::path::Path;
7+
8+
#[derive(Clone, Debug, Deserialize, PartialEq)]
9+
pub struct FallbackSettings {
10+
pub default_toolchain: Option<String>,
11+
}
12+
13+
impl Default for FallbackSettings {
14+
fn default() -> Self {
15+
Self {
16+
default_toolchain: None,
17+
}
18+
}
19+
}
20+
21+
impl FallbackSettings {
22+
pub fn new<P: AsRef<Path>>(path: P) -> Result<Option<Self>> {
23+
// Users cannot fix issues with missing/unreadable/invalid centralised files, but logging isn't setup early so
24+
// we can't simply trap all errors and log diagnostics. Ideally we would, and then separate these into different
25+
// sorts of issues, logging messages about errors that should be fixed. Instead we trap some conservative errors
26+
// that hopefully won't lead to too many tickets.
27+
match utils::read_file("fallback settings", path.as_ref()) {
28+
Err(e @ Error(ErrorKind::ReadingFile { .. }, _)) => {
29+
let io_err = e.source().unwrap().downcast_ref::<io::Error>().unwrap();
30+
match io_err.kind() {
31+
io::ErrorKind::NotFound | io::ErrorKind::PermissionDenied => Ok(None),
32+
_ => Err(e.into()),
33+
}
34+
}
35+
Err(e) => Err(e),
36+
Ok(file_contents) => Ok(Some(
37+
toml::from_str(&file_contents).map_err(ErrorKind::ParsingFallbackSettings)?,
38+
)),
39+
}
40+
}
41+
}

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ pub mod diskio;
5858
pub mod dist;
5959
pub mod env_var;
6060
pub mod errors;
61+
pub mod fallback_settings;
6162
mod install;
6263
mod notifications;
6364
pub mod settings;

0 commit comments

Comments
 (0)