diff --git a/src/sync.rs b/src/sync.rs index f56b790..aaa949c 100644 --- a/src/sync.rs +++ b/src/sync.rs @@ -1,8 +1,8 @@ use crate::SyncContext; use crate::josh::JoshProxy; -use crate::utils::run_command; use crate::utils::run_command_at; use crate::utils::{ensure_clean_git_state, prompt}; +use crate::utils::{run_command, stream_command}; use anyhow::{Context, Error}; use std::path::{Path, PathBuf}; @@ -158,7 +158,8 @@ This merge was created using https://github.com/rust-lang/josh-sync. ); // Merge the fetched commit. - run_command(&[ + // It is useful to print stdout/stderr here, because it shows the git diff summary + stream_command(&[ "git", "merge", "FETCH_HEAD", @@ -301,7 +302,8 @@ fn prepare_rustc_checkout() -> anyhow::Result { println!( "Cloning rustc into `{path}`. Use RUSTC_GIT environment variable to override the location of the checkout" ); - run_command(&[ + // Stream stdout/stderr to the terminal, so that the user sees clone progress + stream_command(&[ "git", "clone", "--filter=blob:none", diff --git a/src/utils.rs b/src/utils.rs index 3091888..fb23724 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -6,9 +6,23 @@ pub fn run_command<'a, Args: AsRef<[&'a str]>>(args: Args) -> anyhow::Result>(args: Args) -> anyhow::Result<()> { + run_command_inner(args, &std::env::current_dir()?, false)?; + Ok(()) +} + pub fn run_command_at<'a, Args: AsRef<[&'a str]>>( args: Args, workdir: &Path, +) -> anyhow::Result { + run_command_inner(args, workdir, true) +} + +fn run_command_inner<'a, Args: AsRef<[&'a str]>>( + args: Args, + workdir: &Path, + capture: bool, ) -> anyhow::Result { let args = args.as_ref(); @@ -17,16 +31,32 @@ pub fn run_command_at<'a, Args: AsRef<[&'a str]>>( cmd.args(&args[1..]); eprintln!("+ {cmd:?}"); - let out = cmd.output().expect("command failed"); - let stdout = String::from_utf8_lossy(out.stdout.trim_ascii()).to_string(); - let stderr = String::from_utf8_lossy(out.stderr.trim_ascii()).to_string(); - if !out.status.success() { - Err(anyhow::anyhow!( - "Command `{cmd:?}` failed with exit code {:?}. STDOUT:\n{stdout}\nSTDERR:\n{stderr}", - out.status.code() - )) + if capture { + let out = cmd.output().expect("command failed"); + let stdout = String::from_utf8_lossy(out.stdout.trim_ascii()).to_string(); + let stderr = String::from_utf8_lossy(out.stderr.trim_ascii()).to_string(); + if !out.status.success() { + Err(anyhow::anyhow!( + "Command `{cmd:?}` failed with exit code {:?}. STDOUT:\n{stdout}\nSTDERR:\n{stderr}", + out.status.code() + )) + } else { + Ok(stdout) + } } else { - Ok(stdout) + let status = cmd + .spawn() + .expect("cannot spawn command") + .wait() + .expect("command failed"); + if !status.success() { + Err(anyhow::anyhow!( + "Command `{cmd:?}` failed with exit code {:?}", + status.code() + )) + } else { + Ok(String::new()) + } } }