Capture output from rustc and rustdoc.

This commit is contained in:
kennytm 2018-08-02 22:18:43 +08:00
parent f1c783b8da
commit 641f7ff2c7
No known key found for this signature in database
GPG key ID: FEF6C8051D0E013C
5 changed files with 60 additions and 6 deletions

View file

@ -65,6 +65,7 @@ core-foundation = { version = "0.6.0", features = ["mac_os_10_7_support"] }
[target.'cfg(windows)'.dependencies]
miow = "0.3.1"
fwdansi = "1"
[target.'cfg(windows)'.dependencies.winapi]
version = "0.3"

View file

@ -306,7 +306,9 @@ impl<'a> JobQueue<'a> {
println!("{}", out);
}
Message::Stderr(err) => {
writeln!(cx.bcx.config.shell().err(), "{}", err)?;
let mut shell = cx.bcx.config.shell();
shell.print_ansi(err.as_bytes())?;
shell.err().write(b"\n")?;
}
Message::FixDiagnostic(msg) => {
print.print(&msg)?;

View file

@ -72,6 +72,18 @@ pub trait Executor: Send + Sync + 'static {
Ok(())
}
fn exec_and_capture_output(
&self,
cmd: ProcessBuilder,
id: &PackageId,
target: &Target,
mode: CompileMode,
_state: &job_queue::JobState<'_>,
) -> CargoResult<()> {
// we forward to exec() to keep RLS working.
self.exec(cmd, id, target, mode)
}
fn exec_json(
&self,
cmd: ProcessBuilder,
@ -97,7 +109,18 @@ pub trait Executor: Send + Sync + 'static {
#[derive(Copy, Clone)]
pub struct DefaultExecutor;
impl Executor for DefaultExecutor {}
impl Executor for DefaultExecutor {
fn exec_and_capture_output(
&self,
cmd: ProcessBuilder,
_id: &PackageId,
_target: &Target,
_mode: CompileMode,
state: &job_queue::JobState<'_>,
) -> CargoResult<()> {
state.capture_output(cmd, false).map(drop)
}
}
fn compile<'a, 'cfg: 'a>(
cx: &mut Context<'a, 'cfg>,
@ -216,6 +239,8 @@ fn rustc<'a, 'cfg>(
.unwrap_or_else(|| cx.bcx.config.cwd())
.to_path_buf();
let should_capture_output = cx.bcx.config.cli_unstable().compile_progress;
return Ok(Work::new(move |state| {
// Only at runtime have we discovered what the extra -L and -l
// arguments are for native libraries, so we process those here. We
@ -291,7 +316,12 @@ fn rustc<'a, 'cfg>(
} else if build_plan {
state.build_plan(buildkey, rustc.clone(), outputs.clone());
} else {
exec.exec(rustc, &package_id, &target, mode)
let exec_result = if should_capture_output {
exec.exec_and_capture_output(rustc, &package_id, &target, mode, state)
} else {
exec.exec(rustc, &package_id, &target, mode)
};
exec_result
.map_err(Internal::new)
.chain_err(|| format!("Could not compile `{}`.", name))?;
}
@ -613,6 +643,8 @@ fn rustdoc<'a, 'cfg>(cx: &mut Context<'a, 'cfg>, unit: &Unit<'a>) -> CargoResult
let build_state = cx.build_state.clone();
let key = (unit.pkg.package_id().clone(), unit.kind);
let should_capture_output = cx.bcx.config.cli_unstable().compile_progress;
Ok(Work::new(move |state| {
if let Some(output) = build_state.outputs.lock().unwrap().get(&key) {
for cfg in output.cfgs.iter() {
@ -623,9 +655,13 @@ fn rustdoc<'a, 'cfg>(cx: &mut Context<'a, 'cfg>, unit: &Unit<'a>) -> CargoResult
}
}
state.running(&rustdoc);
rustdoc
.exec()
.chain_err(|| format!("Could not document `{}`.", name))?;
let exec_result = if should_capture_output {
state.capture_output(rustdoc, false).map(drop)
} else {
rustdoc.exec()
};
exec_result.chain_err(|| format!("Could not document `{}`.", name))?;
Ok(())
}))
}

View file

@ -239,6 +239,19 @@ impl Shell {
ShellOut::Stream { stream, .. } => stream.supports_color(),
}
}
/// Prints a message and translates ANSI escape code into console colors.
pub fn print_ansi(&mut self, message: &[u8]) -> CargoResult<()> {
#[cfg(windows)]
{
if let ShellOut::Stream { stream, .. } = &mut self.err {
::fwdansi::write_ansi(stream, message)?;
return Ok(());
}
}
self.err().write_all(message)?;
Ok(())
}
}
impl Default for Shell {

View file

@ -26,6 +26,8 @@ extern crate failure;
extern crate filetime;
extern crate flate2;
extern crate fs2;
#[cfg(windows)]
extern crate fwdansi;
extern crate git2;
extern crate glob;
extern crate hex;