Skip to content

Commit 039299e

Browse files
Fix 'show' so it displays helpful information if the active toolchain is not installed.
Fixes #1178
1 parent 92d0d1e commit 039299e

File tree

3 files changed

+54
-29
lines changed

3 files changed

+54
-29
lines changed

src/rustup-cli/rustup_mode.rs

Lines changed: 37 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use self_update;
1010
use std::path::Path;
1111
use std::process::Command;
1212
use std::iter;
13+
use std::error::Error;
1314
use term2;
1415
use std::io::{self, Write};
1516
use help::*;
@@ -545,15 +546,21 @@ fn show(cfg: &Cfg) -> Result<()> {
545546

546547
let ref cwd = try!(utils::current_dir());
547548
let installed_toolchains = try!(cfg.list_toolchains());
548-
let active_toolchain = try!(cfg.find_override_toolchain_or_default(cwd));
549-
let active_targets = if let Some((ref t, _)) = active_toolchain {
550-
match t.list_components() {
551-
Ok(cs_vec) => cs_vec
552-
.into_iter()
553-
.filter(|c| c.component.pkg == "rust-std")
554-
.filter(|c| c.installed)
555-
.collect(),
556-
Err(_) => vec![]
549+
let active_toolchain = cfg.find_override_toolchain_or_default(cwd);
550+
551+
// active_toolchain will carry the reason we don't have one in its detail.
552+
let active_targets = if let Ok(ref at) = active_toolchain {
553+
if let Some((ref t, _)) = *at {
554+
match t.list_components() {
555+
Ok(cs_vec) => cs_vec
556+
.into_iter()
557+
.filter(|c| c.component.pkg == "rust-std")
558+
.filter(|c| c.installed)
559+
.collect(),
560+
Err(_) => vec![]
561+
}
562+
} else {
563+
vec![]
557564
}
558565
} else {
559566
vec![]
@@ -572,9 +579,7 @@ fn show(cfg: &Cfg) -> Result<()> {
572579

573580
if show_installed_toolchains {
574581
if show_headers { print_header("installed toolchains") }
575-
let default = try!(cfg.find_default());
576-
let default_name = default.map(|t| t.name().to_string())
577-
.unwrap_or("".into());
582+
let default_name = try!(cfg.get_default());
578583
for t in installed_toolchains {
579584
if default_name == t {
580585
println!("{} (default)", t);
@@ -599,16 +604,27 @@ fn show(cfg: &Cfg) -> Result<()> {
599604
if show_headers { print_header("active toolchain") }
600605

601606
match active_toolchain {
602-
Some((ref toolchain, Some(ref reason))) => {
603-
println!("{} ({})", toolchain.name(), reason);
604-
println!("{}", common::rustc_version(toolchain));
605-
}
606-
Some((ref toolchain, None)) => {
607-
println!("{} (default)", toolchain.name());
608-
println!("{}", common::rustc_version(toolchain));
607+
Ok(atc) => {
608+
match atc {
609+
Some((ref toolchain, Some(ref reason))) => {
610+
println!("{} ({})", toolchain.name(), reason);
611+
println!("{}", common::rustc_version(toolchain));
612+
}
613+
Some((ref toolchain, None)) => {
614+
println!("{} (default)", toolchain.name());
615+
println!("{}", common::rustc_version(toolchain));
616+
}
617+
None => {
618+
println!("no active toolchain");
619+
}
620+
}
609621
}
610-
None => {
611-
println!("no active toolchain");
622+
Err(err) => {
623+
if let Some(cause) = err.cause() {
624+
println!("(error: {}, {})", err, cause);
625+
} else {
626+
println!("(error: {})", err);
627+
}
612628
}
613629
}
614630

src/rustup/config.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,14 @@ impl Cfg {
326326
})
327327
}
328328

329+
pub fn get_default(&self) -> Result<String> {
330+
self.settings_file.with(|s| {
331+
Ok(s.default_toolchain.clone().unwrap())
332+
})
333+
}
334+
335+
336+
329337
pub fn list_toolchains(&self) -> Result<Vec<String>> {
330338
if utils::is_directory(&self.toolchains_dir) {
331339
let mut toolchains: Vec<_> = try!(utils::read_dir("toolchains", &self.toolchains_dir))

tests/cli-rustup.rs

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ extern crate rustup_dist;
44
extern crate rustup_utils;
55
extern crate rustup_mock;
66
extern crate tempdir;
7+
extern crate regex;
78

89
use std::fs;
910
use std::env::consts::EXE_SUFFIX;
@@ -15,6 +16,7 @@ use rustup_mock::clitools::{self, Config, Scenario,
1516
expect_err,
1617
set_current_dist_date,
1718
this_host_triple, change_dir};
19+
use regex::Regex;
1820

1921
macro_rules! for_host { ($s: expr) => (&format!($s, this_host_triple())) }
2022

@@ -624,11 +626,10 @@ fn show_toolchain_override_not_installed() {
624626
let mut cmd = clitools::cmd(config, "rustup", &["show"]);
625627
clitools::env(config, &mut cmd);
626628
let out = cmd.output().unwrap();
627-
assert!(!out.status.success());
628-
let stderr = String::from_utf8(out.stderr).unwrap();
629-
assert!(stderr.starts_with(
630-
for_host!("error: override toolchain 'nightly-{0}' is not installed")));
631-
assert!(!stderr.contains("info: caused by: not a directory: "));
629+
assert!(out.status.success());
630+
let stdout = String::from_utf8(out.stdout).unwrap();
631+
assert!(!stdout.contains("not a directory"));
632+
assert!(Regex::new(r"error: override toolchain 'nightly.*' is not installed, the directory override for '.*' specifies an uninstalled toolchain").unwrap().is_match(&stdout))
632633
});
633634
}
634635

@@ -659,9 +660,9 @@ fn show_toolchain_env_not_installed() {
659660
let out = cmd.output().unwrap();
660661
// I'm not sure this should really be erroring when the toolchain
661662
// is not installed; just capturing the behavior.
662-
assert!(!out.status.success());
663-
let stderr = String::from_utf8(out.stderr).unwrap();
664-
assert!(stderr.starts_with("error: override toolchain 'nightly' is not installed\n"));
663+
assert!(out.status.success());
664+
let stdout = String::from_utf8(out.stdout).unwrap();
665+
assert!(stdout.contains("override toolchain 'nightly' is not installed, the RUSTUP_TOOLCHAIN environment variable specifies an uninstalled toolchain"));
665666
});
666667
}
667668

0 commit comments

Comments
 (0)