From 9597bcea427489f43303d5c27c494674511cec0c Mon Sep 17 00:00:00 2001 From: kennytm Date: Wed, 12 Sep 2018 11:32:27 +0800 Subject: [PATCH] Do not add --color to rustdoc if it doesn't support it. We detect this by executing `rustdoc --color never -V` and see if the result is successful. To avoid repeatedly creating a new process, we cache the result into `.rustc_info.json`. --- src/cargo/core/compiler/mod.rs | 9 +++++++-- src/cargo/util/rustc.rs | 29 +++++++++++++++++++++++++++++ tests/testsuite/rustdoc.rs | 12 ++++++------ 3 files changed, 42 insertions(+), 8 deletions(-) diff --git a/src/cargo/core/compiler/mod.rs b/src/cargo/core/compiler/mod.rs index 8282f6caeb7..10c362e2a16 100644 --- a/src/cargo/core/compiler/mod.rs +++ b/src/cargo/core/compiler/mod.rs @@ -13,7 +13,7 @@ use core::profiles::{Lto, Profile}; use core::{PackageId, Target}; use util::errors::{CargoResult, CargoResultExt, Internal}; use util::paths; -use util::{self, machine_message, Freshness, ProcessBuilder}; +use util::{self, machine_message, Freshness, ProcessBuilder, process}; use util::{internal, join_paths, profile}; use self::build_plan::BuildPlan; @@ -583,7 +583,12 @@ fn rustdoc<'a, 'cfg>(cx: &mut Context<'a, 'cfg>, unit: &Unit<'a>) -> CargoResult rustdoc.arg("--crate-name").arg(&unit.target.crate_name()); add_path_args(bcx, unit, &mut rustdoc); add_cap_lints(bcx, unit, &mut rustdoc); - add_color(bcx, &mut rustdoc); + + let mut can_add_color_process = process(&*bcx.config.rustdoc()?); + can_add_color_process.args(&["--color", "never", "-V"]); + if bcx.rustc.cached_success(&can_add_color_process)? { + add_color(bcx, &mut rustdoc); + } if unit.kind != Kind::Host { if let Some(ref target) = bcx.build_config.requested_target { diff --git a/src/cargo/util/rustc.rs b/src/cargo/util/rustc.rs index af6d6312131..0852d6307f1 100644 --- a/src/cargo/util/rustc.rs +++ b/src/cargo/util/rustc.rs @@ -4,6 +4,7 @@ use std::path::{Path, PathBuf}; use std::hash::{Hash, Hasher, SipHasher}; use std::collections::hash_map::{Entry, HashMap}; use std::sync::Mutex; +use std::process::Stdio; use std::env; use serde_json; @@ -83,6 +84,10 @@ impl Rustc { pub fn cached_output(&self, cmd: &ProcessBuilder) -> CargoResult<(String, String)> { self.cache.lock().unwrap().cached_output(cmd) } + + pub fn cached_success(&self, cmd: &ProcessBuilder) -> CargoResult { + self.cache.lock().unwrap().cached_success(cmd) + } } /// It is a well known that `rustc` is not the fastest compiler in the world. @@ -104,6 +109,7 @@ struct Cache { struct CacheData { rustc_fingerprint: u64, outputs: HashMap, + successes: HashMap, } impl Cache { @@ -113,6 +119,7 @@ impl Cache { let empty = CacheData { rustc_fingerprint, outputs: HashMap::new(), + successes: HashMap::new(), }; let mut dirty = true; let data = match read(&cache_location) { @@ -177,6 +184,28 @@ impl Cache { } } } + + fn cached_success(&mut self, cmd: &ProcessBuilder) -> CargoResult { + let key = process_fingerprint(cmd); + match self.data.successes.entry(key) { + Entry::Occupied(entry) => { + info!("rustc info cache hit"); + Ok(*entry.get()) + } + Entry::Vacant(entry) => { + info!("rustc info cache miss"); + let success = cmd + .build_command() + .stdout(Stdio::null()) + .stderr(Stdio::null()) + .status()? + .success(); + entry.insert(success); + self.dirty = true; + Ok(success) + } + } + } } impl Drop for Cache { diff --git a/tests/testsuite/rustdoc.rs b/tests/testsuite/rustdoc.rs index 6b50966558c..35110349fee 100644 --- a/tests/testsuite/rustdoc.rs +++ b/tests/testsuite/rustdoc.rs @@ -8,7 +8,7 @@ fn rustdoc_simple() { .with_stderr( "\ [DOCUMENTING] foo v0.0.1 ([CWD]) -[RUNNING] `rustdoc --crate-name foo src/lib.rs --color never \ +[RUNNING] `rustdoc --crate-name foo src/lib.rs [..]\ -o [CWD]/target/doc \ -L dependency=[CWD]/target/debug/deps` [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] @@ -24,7 +24,7 @@ fn rustdoc_args() { .with_stderr( "\ [DOCUMENTING] foo v0.0.1 ([CWD]) -[RUNNING] `rustdoc --crate-name foo src/lib.rs --color never \ +[RUNNING] `rustdoc --crate-name foo src/lib.rs [..]\ -o [CWD]/target/doc \ --cfg=foo \ -L dependency=[CWD]/target/debug/deps` @@ -61,7 +61,7 @@ fn rustdoc_foo_with_bar_dependency() { [CHECKING] bar v0.0.1 ([..]) [RUNNING] `rustc [..]bar/src/lib.rs [..]` [DOCUMENTING] foo v0.0.1 ([CWD]) -[RUNNING] `rustdoc --crate-name foo src/lib.rs --color never \ +[RUNNING] `rustdoc --crate-name foo src/lib.rs [..]\ -o [CWD]/target/doc \ --cfg=foo \ -L dependency=[CWD]/target/debug/deps \ @@ -97,7 +97,7 @@ fn rustdoc_only_bar_dependency() { .with_stderr( "\ [DOCUMENTING] bar v0.0.1 ([..]) -[RUNNING] `rustdoc --crate-name bar [..]bar/src/lib.rs --color never \ +[RUNNING] `rustdoc --crate-name bar [..]bar/src/lib.rs [..]\ -o [CWD]/target/doc \ --cfg=foo \ -L dependency=[CWD]/target/debug/deps` @@ -117,7 +117,7 @@ fn rustdoc_same_name_documents_lib() { .with_stderr( "\ [DOCUMENTING] foo v0.0.1 ([..]) -[RUNNING] `rustdoc --crate-name foo src/lib.rs --color never \ +[RUNNING] `rustdoc --crate-name foo src/lib.rs [..]\ -o [CWD]/target/doc \ --cfg=foo \ -L dependency=[CWD]/target/debug/deps` @@ -161,7 +161,7 @@ fn rustdoc_target() { .with_stderr( "\ [DOCUMENTING] foo v0.0.1 ([..]) -[RUNNING] `rustdoc --crate-name foo src/lib.rs --color never \ +[RUNNING] `rustdoc --crate-name foo src/lib.rs [..]\ --target x86_64-unknown-linux-gnu \ -o [CWD]/target/x86_64-unknown-linux-gnu/doc \ -L dependency=[CWD]/target/x86_64-unknown-linux-gnu/debug/deps \