]> git.lizzy.rs Git - rust.git/commitdiff
Make rustc errors colorful.
authorMark Simulacrum <mark.simulacrum@gmail.com>
Wed, 21 Jun 2017 16:04:21 +0000 (10:04 -0600)
committerMark Simulacrum <mark.simulacrum@gmail.com>
Wed, 21 Jun 2017 16:04:21 +0000 (10:04 -0600)
Rustbuild passes --message-format=json to Cargo to learn about the
dependencies for a given build, which then makes Cargo steal the
stderr/stdout for the compiler process, leading to non colorful output.
To avoid this, detection of stderr being a tty is added to rustbuild,
and an environment variable is used to communicate with the rustc shim.

src/bootstrap/bin/rustc.rs
src/bootstrap/compile.rs

index 12152fc439901cea052eddc52a04f8a5ab901358..8c6eaee24f2943ea76c3cf86e41bb8cb3dd65fec 100644 (file)
@@ -236,6 +236,15 @@ fn main() {
         }
     }
 
+    let color = match env::var("RUSTC_COLOR") {
+        Ok(s) => usize::from_str(&s).expect("RUSTC_COLOR should be an integer"),
+        Err(_) => 0,
+    };
+
+    if color != 0 {
+        cmd.arg("--color=always");
+    }
+
     if verbose > 1 {
         writeln!(&mut io::stderr(), "rustc command: {:?}", cmd).unwrap();
     }
index 9a07e8a8b1091da983213917f9ab46fd7be21630..f92a199fa3fea08b459f5739c80229eeeafa08ba 100644 (file)
@@ -477,11 +477,43 @@ pub fn tool(build: &Build, stage: u32, target: &str, tool: &str) {
     build.run(&mut cargo);
 }
 
+
+// Avoiding a dependency on winapi to keep compile times down
+#[cfg(unix)]
+fn stderr_isatty() -> bool {
+    use libc;
+    unsafe { libc::isatty(libc::STDERR_FILENO) != 0 }
+}
+#[cfg(windows)]
+fn stderr_isatty() -> bool {
+    type DWORD = u32;
+    type BOOL = i32;
+    type HANDLE = *mut u8;
+    const STD_ERROR_HANDLE: DWORD = -12i32 as DWORD;
+    extern "system" {
+        fn GetStdHandle(which: DWORD) -> HANDLE;
+        fn GetConsoleMode(hConsoleHandle: HANDLE, lpMode: *mut DWORD) -> BOOL;
+    }
+    unsafe {
+        let handle = GetStdHandle(STD_ERROR_HANDLE);
+        let mut out = 0;
+        GetConsoleMode(handle, &mut out) != 0
+    }
+}
+
 fn run_cargo(build: &Build, cargo: &mut Command, stamp: &Path) {
     // Instruct Cargo to give us json messages on stdout, critically leaving
     // stderr as piped so we can get those pretty colors.
     cargo.arg("--message-format").arg("json")
          .stdout(Stdio::piped());
+
+    if stderr_isatty() {
+        // since we pass message-format=json to cargo, we need to tell the rustc
+        // wrapper to give us colored output if necessary. This is because we
+        // only want Cargo's JSON output, not rustcs.
+        cargo.env("RUSTC_COLOR", "1");
+    }
+
     build.verbose(&format!("running: {:?}", cargo));
     let mut child = match cargo.spawn() {
         Ok(child) => child,