Skip to content

Commit 3e7c66f

Browse files
committed
Add toolchain override support on command line
1 parent 0fada4f commit 3e7c66f

File tree

3 files changed

+108
-7
lines changed

3 files changed

+108
-7
lines changed

src/cli/rustup_mode.rs

+14-6
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@ pub fn main() -> Result<()> {
3535
let quiet = matches.is_present("quiet");
3636
let cfg = &mut common::set_globals(verbose, quiet)?;
3737

38+
if let Some(t) = matches.value_of("+toolchain") {
39+
cfg.set_toolchain_override(&t[1..]);
40+
}
41+
3842
if maybe_upgrade_data(cfg, &matches)? {
3943
return Ok(());
4044
}
@@ -131,10 +135,15 @@ pub fn cli() -> App<'static, 'static> {
131135
.long("quiet"),
132136
)
133137
.arg(
134-
Arg::with_name("toolchain")
135-
.help(TOOLCHAIN_ARG_HELP)
136-
.long("toolchain")
137-
.takes_value(true),
138+
Arg::with_name("+toolchain")
139+
.help("release channel (e.g. +stable) or custom toolchain to set override")
140+
.validator(|s| {
141+
if s.starts_with('+') {
142+
Ok(())
143+
} else {
144+
Err("Toolchain overrides must begin with '+'".into())
145+
}
146+
}),
138147
)
139148
.subcommand(
140149
SubCommand::with_name("dump-testament")
@@ -852,8 +861,7 @@ fn run(cfg: &Cfg, m: &ArgMatches<'_>) -> Result<()> {
852861

853862
fn which(cfg: &Cfg, m: &ArgMatches<'_>) -> Result<()> {
854863
let binary = m.value_of("command").expect("");
855-
let toolchain_provided = m.is_present("toolchain");
856-
let binary_path = if toolchain_provided {
864+
let binary_path = if m.is_present("toolchain") {
857865
let toolchain = m.value_of("toolchain").expect("");
858866
cfg.which_binary_by_toolchain(toolchain, binary)?
859867
.expect("binary not found")

src/config.rs

+18-1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ use crate::utils::utils;
1717
#[derive(Debug)]
1818
pub enum OverrideReason {
1919
Environment,
20+
CommandLine,
2021
OverrideDB(PathBuf),
2122
ToolchainFile(PathBuf),
2223
}
@@ -25,6 +26,7 @@ impl Display for OverrideReason {
2526
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> std::result::Result<(), fmt::Error> {
2627
match self {
2728
Self::Environment => write!(f, "environment override by RUSTUP_TOOLCHAIN"),
29+
Self::CommandLine => write!(f, "overridden by +toolchain on the command line"),
2830
Self::OverrideDB(path) => write!(f, "directory override for '{}'", path.display()),
2931
Self::ToolchainFile(path) => write!(f, "overridden by '{}'", path.display()),
3032
}
@@ -40,6 +42,7 @@ pub struct Cfg {
4042
pub download_dir: PathBuf,
4143
pub temp_cfg: temp::Cfg,
4244
pub gpg_key: Cow<'static, str>,
45+
pub toolchain_override: Option<String>,
4346
pub env_override: Option<String>,
4447
pub dist_root_url: String,
4548
pub dist_root_server: String,
@@ -104,6 +107,7 @@ impl Cfg {
104107
temp_cfg,
105108
gpg_key,
106109
notify_handler,
110+
toolchain_override: None,
107111
env_override,
108112
dist_root_url: dist_root,
109113
dist_root_server,
@@ -144,6 +148,10 @@ impl Cfg {
144148
Ok(())
145149
}
146150

151+
pub fn set_toolchain_override(&mut self, toolchain_override: &str) {
152+
self.toolchain_override = Some(toolchain_override.to_owned());
153+
}
154+
147155
// Returns a profile, if one exists in the settings file.
148156
//
149157
// Returns `Err` if the settings file could not be read or the profile is
@@ -281,7 +289,12 @@ impl Cfg {
281289
pub fn find_override(&self, path: &Path) -> Result<Option<(Toolchain<'_>, OverrideReason)>> {
282290
let mut override_ = None;
283291

284-
// First check RUSTUP_TOOLCHAIN
292+
// First check toolchain override from command
293+
if let Some(ref name) = self.toolchain_override {
294+
override_ = Some((name.to_string(), OverrideReason::CommandLine));
295+
}
296+
297+
// Check RUSTUP_TOOLCHAIN
285298
if let Some(ref name) = self.env_override {
286299
override_ = Some((name.to_string(), OverrideReason::Environment));
287300
}
@@ -306,6 +319,10 @@ impl Cfg {
306319
"the RUSTUP_TOOLCHAIN environment variable specifies an uninstalled toolchain"
307320
.to_string()
308321
}
322+
OverrideReason::CommandLine => {
323+
"the +toolchain on the command line specifies an uninstalled toolchain"
324+
.to_string()
325+
}
309326
OverrideReason::OverrideDB(ref path) => format!(
310327
"the directory override for '{}' specifies an uninstalled toolchain",
311328
path.display()

tests/cli-misc.rs

+76
Original file line numberDiff line numberDiff line change
@@ -905,3 +905,79 @@ fn which() {
905905
);
906906
});
907907
}
908+
909+
#[test]
910+
fn override_by_toolchain_on_the_command_line() {
911+
setup(&|config| {
912+
#[cfg(windows)]
913+
expect_stdout_ok(
914+
config,
915+
&["rustup", "+stable", "which", "rustc"],
916+
"\\toolchains\\stable-x86_64-",
917+
);
918+
#[cfg(windows)]
919+
expect_stdout_ok(
920+
config,
921+
&["rustup", "+stable", "which", "rustc"],
922+
"\\bin\\rustc",
923+
);
924+
#[cfg(not(windows))]
925+
expect_stdout_ok(
926+
config,
927+
&["rustup", "+stable", "which", "rustc"],
928+
"/toolchains/stable-x86_64-",
929+
);
930+
#[cfg(not(windows))]
931+
expect_stdout_ok(
932+
config,
933+
&["rustup", "+stable", "which", "rustc"],
934+
"/bin/rustc",
935+
);
936+
expect_ok(config, &["rustup", "default", "nightly"]);
937+
#[cfg(windows)]
938+
expect_stdout_ok(
939+
config,
940+
&["rustup", "+nightly", "which", "rustc"],
941+
"\\toolchains\\nightly-x86_64-",
942+
);
943+
#[cfg(windows)]
944+
expect_stdout_ok(
945+
config,
946+
&["rustup", "+nightly", "which", "rustc"],
947+
"\\bin\\rustc",
948+
);
949+
#[cfg(not(windows))]
950+
expect_stdout_ok(
951+
config,
952+
&["rustup", "+nightly", "which", "rustc"],
953+
"/toolchains/nightly-x86_64-",
954+
);
955+
#[cfg(not(windows))]
956+
expect_stdout_ok(
957+
config,
958+
&["rustup", "+nightly", "which", "rustc"],
959+
"/bin/rustc",
960+
);
961+
expect_stdout_ok(
962+
config,
963+
&["rustup", "+nightly", "show"],
964+
"(overridden by +toolchain on the command line)",
965+
);
966+
expect_err(
967+
config,
968+
&["rustup", "+foo", "which", "rustc"],
969+
"toolchain 'foo' is not installed",
970+
);
971+
expect_err(
972+
config,
973+
&["rustup", "@stable", "which", "rustc"],
974+
"Invalid value for '<+toolchain>': Toolchain overrides must begin with '+'",
975+
);
976+
expect_stderr_ok(
977+
config,
978+
&["rustup", "+stable", "set", "profile", "minimal"],
979+
"profile set to 'minimal'",
980+
);
981+
expect_stdout_ok(config, &["rustup", "default"], "nightly-x86_64-");
982+
});
983+
}

0 commit comments

Comments
 (0)