Skip to content

Commit b697df1

Browse files
authored
Merge pull request #1578 from kinnison/kinnison/fix-745
Deal cleanly with malformed default-host
2 parents 104c45e + 36ec58f commit b697df1

File tree

5 files changed

+97
-15
lines changed

5 files changed

+97
-15
lines changed

src/rustup-cli/log.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ macro_rules! verbose {
1616
( $ ( $ arg : tt ) * ) => ( $crate::log::verbose_fmt ( format_args ! ( $ ( $ arg ) * ) ) )
1717
}
1818

19+
macro_rules! debug {
20+
( $ ( $ arg : tt ) * ) => ( $crate::log::debug_fmt ( format_args ! ( $ ( $ arg ) * ) ) )
21+
}
22+
1923
pub fn warn_fmt(args: fmt::Arguments) {
2024
let mut t = term2::stderr();
2125
let _ = t.fg(term2::color::BRIGHT_YELLOW);
@@ -54,3 +58,15 @@ pub fn verbose_fmt(args: fmt::Arguments) {
5458
let _ = t.write_fmt(args);
5559
let _ = write!(t, "\n");
5660
}
61+
62+
pub fn debug_fmt(args: fmt::Arguments) {
63+
if std::env::var("RUSTUP_DEBUG").is_ok() {
64+
let mut t = term2::stderr();
65+
let _ = t.fg(term2::color::BRIGHT_BLUE);
66+
let _ = t.attr(term2::Attr::Bold);
67+
let _ = write!(t, "verbose: ");
68+
let _ = t.reset();
69+
let _ = t.write_fmt(args);
70+
let _ = write!(t, "\n");
71+
}
72+
}

src/rustup-cli/self_update.rs

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,7 @@ fn canonical_cargo_home() -> Result<String> {
223223
/// and adding `CARGO_HOME`/bin to PATH.
224224
pub fn install(no_prompt: bool, verbose: bool, mut opts: InstallOpts) -> Result<()> {
225225
do_pre_install_sanity_checks()?;
226+
do_pre_install_options_sanity_checks(&opts)?;
226227
check_existence_of_rustc_or_cargo_in_path(no_prompt)?;
227228
do_anti_sudo_check(no_prompt)?;
228229

@@ -454,7 +455,7 @@ fn do_pre_install_sanity_checks() -> Result<()> {
454455
"delete `{}` to remove rustup.sh",
455456
rustup_sh_path.expect("").display()
456457
);
457-
warn!("or, if you already rustup installed, you can run");
458+
warn!("or, if you already have rustup installed, you can run");
458459
warn!("`rustup self update` and `rustup toolchain list` to upgrade");
459460
warn!("your directory structure");
460461
return Err("cannot install while rustup.sh is installed".into());
@@ -463,6 +464,35 @@ fn do_pre_install_sanity_checks() -> Result<()> {
463464
Ok(())
464465
}
465466

467+
fn do_pre_install_options_sanity_checks(opts: &InstallOpts) -> Result<()> {
468+
// Verify that the installation options are vaguely sane
469+
(|| {
470+
let host_triple = dist::TargetTriple::from_str(&opts.default_host_triple);
471+
let toolchain_to_use = if opts.default_toolchain == "none" {
472+
"stable"
473+
} else {
474+
&opts.default_toolchain
475+
};
476+
let partial_channel = dist::PartialToolchainDesc::from_str(toolchain_to_use)?;
477+
let resolved = partial_channel.resolve(&host_triple)?.to_string();
478+
debug!(
479+
"Successfully resolved installation toolchain as: {}",
480+
resolved
481+
);
482+
Ok(())
483+
})()
484+
.map_err(|e: Box<std::error::Error>| {
485+
format!(
486+
"Pre-checks for host and toolchain failed: {}\n\
487+
If you are unsure of suitable values, the 'stable' toolchain is the default.\n\
488+
Valid host triples look something like: {}",
489+
e,
490+
dist::TargetTriple::from_host_or_build()
491+
)
492+
})?;
493+
Ok(())
494+
}
495+
466496
// If the user is trying to install with sudo, on some systems this will
467497
// result in writing root-owned files to the user's home directory, because
468498
// sudo is configured not to change $HOME. Don't let that bogosity happen.

src/rustup-dist/src/dist.rs

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -291,11 +291,25 @@ impl PartialToolchainDesc {
291291
}
292292
}
293293

294-
pub fn resolve(self, host: &TargetTriple) -> ToolchainDesc {
295-
let host = PartialTargetTriple::from_str(&host.0)
296-
.expect("host triple couldn't be converted to partial triple");
297-
let host_arch = host.arch.expect("");
298-
let host_os = host.os.expect("");
294+
pub fn resolve(self, input_host: &TargetTriple) -> Result<ToolchainDesc> {
295+
let host = PartialTargetTriple::from_str(&input_host.0).ok_or_else(|| {
296+
format!(
297+
"Provided host '{}' couldn't be converted to partial triple",
298+
input_host.0
299+
)
300+
})?;
301+
let host_arch = host.arch.ok_or_else(|| {
302+
format!(
303+
"Provided host '{}' did not specify a CPU architecture",
304+
input_host.0
305+
)
306+
})?;
307+
let host_os = host.os.ok_or_else(|| {
308+
format!(
309+
"Provided host '{}' did not specify an operating system",
310+
input_host.0
311+
)
312+
})?;
299313
let host_env = host.env;
300314

301315
// If OS was specified, don't default to host environment, even if the OS matches
@@ -314,11 +328,11 @@ impl PartialToolchainDesc {
314328
format!("{}-{}", arch, os)
315329
};
316330

317-
ToolchainDesc {
331+
Ok(ToolchainDesc {
318332
channel: self.channel,
319333
date: self.date,
320334
target: TargetTriple(trip),
321-
}
335+
})
322336
}
323337

324338
pub fn has_triple(&self) -> bool {

src/rustup/config.rs

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ impl Cfg {
9999
);
100100
let dist_root = dist_root_server.clone() + "/dist";
101101

102-
Ok(Cfg {
102+
let cfg = Cfg {
103103
rustup_dir: rustup_dir,
104104
settings_file: settings_file,
105105
toolchains_dir: toolchains_dir,
@@ -111,7 +111,15 @@ impl Cfg {
111111
env_override: env_override,
112112
dist_root_url: dist_root,
113113
dist_root_server: dist_root_server,
114-
})
114+
};
115+
116+
// Run some basic checks against the constructed configuration
117+
// For now, that means simply checking that 'stable' can resolve
118+
// for the current configuration.
119+
cfg.resolve_toolchain("stable")
120+
.map_err(|e| format!("Unable parse configuration: {}", e))?;
121+
122+
Ok(cfg)
115123
}
116124

117125
pub fn set_default(&self, toolchain: &str) -> Result<()> {
@@ -470,9 +478,11 @@ impl Cfg {
470478
}
471479

472480
pub fn set_default_host_triple(&self, host_triple: &str) -> Result<()> {
473-
if dist::PartialTargetTriple::from_str(host_triple).is_none() {
474-
return Err("Invalid host triple".into());
475-
}
481+
// Ensure that the provided host_triple is capable of resolving
482+
// against the 'stable' toolchain. This provides early errors
483+
// if the supplied triple is insufficient / bad.
484+
dist::PartialToolchainDesc::from_str("stable")?
485+
.resolve(&dist::TargetTriple::from_str(host_triple))?;
476486
self.settings_file.with_mut(|s| {
477487
s.default_host_triple = Some(host_triple.to_owned());
478488
Ok(())
@@ -493,7 +503,7 @@ impl Cfg {
493503
pub fn resolve_toolchain(&self, name: &str) -> Result<String> {
494504
if let Ok(desc) = dist::PartialToolchainDesc::from_str(name) {
495505
let host = self.get_default_host_triple()?;
496-
Ok(desc.resolve(&host).to_string())
506+
Ok(desc.resolve(&host)?.to_string())
497507
} else {
498508
Ok(name.to_owned())
499509
}

tests/cli-rustup.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -900,7 +900,19 @@ fn set_default_host_invalid_triple() {
900900
expect_err(
901901
config,
902902
&["rustup", "set", "default-host", "foo"],
903-
"Invalid host triple",
903+
"error: Provided host 'foo' couldn't be converted to partial triple",
904+
);
905+
});
906+
}
907+
908+
// #745
909+
#[test]
910+
fn set_default_host_invalid_triple_valid_partial() {
911+
setup(&|config| {
912+
expect_err(
913+
config,
914+
&["rustup", "set", "default-host", "x86_64-msvc"],
915+
"error: Provided host 'x86_64-msvc' did not specify an operating system",
904916
);
905917
});
906918
}

0 commit comments

Comments
 (0)