Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 37 additions & 29 deletions src/toolchain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -284,47 +284,55 @@ impl<'a> Toolchain<'a> {
#[tracing::instrument(level = "trace")]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggest adding some snapshot tests to better demonstrate this new feature.

pub fn rustc_version(&self) -> String {
match self.create_command("rustc") {
Err(e) => format!("(rustc does not exist: {e})"),
Ok(mut cmd) => {
cmd.arg("--version");
cmd.stdin(Stdio::null());
cmd.stdout(Stdio::piped());
cmd.stderr(Stdio::piped());
self.set_ldpath(&mut cmd);

// some toolchains are faulty with some combinations of platforms and
// may fail to launch but also to timely terminate.
// (known cases include Rust 1.3.0 through 1.10.0 in recent macOS Sierra.)
// we guard against such cases by enforcing a reasonable timeout to read.
let mut line1 = None;
if let Ok(mut child) = cmd.spawn() {
let timeout = Duration::new(10, 0);
match child.wait_timeout(timeout) {
Ok(Some(status)) if status.success() => {
let out = child
.stdout
.expect("Child::stdout requested but not present");
let mut line = String::new();
if BufReader::new(out).read_line(&mut line).is_ok() {
let lineend = line.trim_end_matches(&['\r', '\n'][..]).len();
line.truncate(lineend);
line1 = Some(line);
match cmd.spawn() {
Comment on lines 294 to +295
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: could try to reduce some rightward drift here and in sections below. Something along the lines of:

let mut child =  match cmd.spawn() {
    Err(e) => return format!("(error reading rustc version: {e})"),
    Ok(child) => child,
};
[..]

Err(e) => {
format!("(error reading rustc version: {e})")
}
// some toolchains are faulty with some combinations of platforms and
// may fail to launch but also to timely terminate.
// (known cases include Rust 1.3.0 through 1.10.0 in recent macOS Sierra.)
// we guard against such cases by enforcing a reasonable timeout to read.
Ok(mut child) => {
let timeout = Duration::new(10, 0);
match child.wait_timeout(timeout) {
Ok(None) => {
let _ = child.kill();
String::from("(timeout reading rustc version)")
}
Err(e) => {
format!("(error reading rustc version: {e})")
}
Ok(Some(status)) => {
if !status.success() {
return format!("(error reading rustc version: {status})");
}

let out = child
.stdout
.expect("Child::stdout requested but not present");
let mut line = String::new();
match BufReader::new(out).read_line(&mut line) {
Ok(_) => {
let lineend =
line.trim_end_matches(&['\r', '\n'][..]).len();
line.truncate(lineend);
line
}
Err(e) => format!("(error reading rustc version: {e})"),
}
}
}
Ok(None) => {
let _ = child.kill();
return String::from("(timeout reading rustc version)");
}
Ok(Some(_)) | Err(_) => {}
}
}

if let Some(line1) = line1 {
line1
} else {
String::from("(error reading rustc version)")
}
}
Err(_) => String::from("(rustc does not exist)"),
}
}

Expand Down