From 09b584809b437ae6a24da7bdb251b7e1c2a3609f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 14 Dec 2017 22:54:08 -0800 Subject: [PATCH] Add env flags `RUSTC_COLOR` and `RUSTC_ERROR_FORMAT` --- src/bootstrap/bin/rustc.rs | 9 ----- src/bootstrap/compile.rs | 2 +- src/librustc/session/config.rs | 50 +++++++++++++++++++------ src/librustc_driver/lib.rs | 4 +- src/librustc_errors/emitter.rs | 68 ++++++++++++++++++++++++++++++++++ src/librustc_errors/lib.rs | 2 +- 6 files changed, 111 insertions(+), 24 deletions(-) diff --git a/src/bootstrap/bin/rustc.rs b/src/bootstrap/bin/rustc.rs index 37336a56d76c2..ce8d012a9db57 100644 --- a/src/bootstrap/bin/rustc.rs +++ b/src/bootstrap/bin/rustc.rs @@ -269,15 +269,6 @@ fn main() { cmd.arg("--cfg").arg("parallel_queries"); } - 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 { eprintln!("rustc command: {:?}", cmd); } diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index 4c76230ced8bc..f340ac77f5eec 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -799,7 +799,7 @@ fn run_cargo(build: &Build, cargo: &mut Command, stamp: &Path) { // 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"); + cargo.env("RUSTC_COLOR", "always"); } build.verbose(&format!("running: {:?}", cargo)); diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 6ad9bd94bf25c..cc53058f67416 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -33,7 +33,7 @@ use syntax::parse; use syntax::symbol::Symbol; use syntax::feature_gate::UnstableFeatures; -use errors::{ColorConfig, FatalError, Handler}; +use errors::{self, ColorConfig, FatalError, Handler, ErrorFormat}; use getopts; use std::collections::{BTreeMap, BTreeSet}; @@ -1540,14 +1540,15 @@ pub fn parse_cfgspecs(cfgspecs: Vec ) -> ast::CrateConfig { }).collect::() } -pub fn build_session_options_and_crate_config(matches: &getopts::Matches) +pub fn build_session_options_and_crate_config(matches: &getopts::Matches, + defaults: errors::EnvDefaults) -> (Options, ast::CrateConfig) { let color = match matches.opt_str("color").as_ref().map(|s| &s[..]) { Some("auto") => ColorConfig::Auto, Some("always") => ColorConfig::Always, Some("never") => ColorConfig::Never, - None => ColorConfig::Auto, + None => defaults.color, Some(arg) => { early_error(ErrorOutputType::default(), &format!("argument for --color must be auto, \ @@ -1574,8 +1575,10 @@ pub fn build_session_options_and_crate_config(matches: &getopts::Matches) enable the short error message option")); } } - None => ErrorOutputType::HumanReadable(color), - + None => match (defaults.error_format, nightly_options::is_nightly_build()) { + (ErrorFormat::Short, true) => ErrorOutputType::Short(color), + _ => ErrorOutputType::HumanReadable(color), + }, Some(arg) => { early_error(ErrorOutputType::HumanReadable(color), &format!("argument for --error-format must be `human`, `json` or \ @@ -1584,7 +1587,10 @@ pub fn build_session_options_and_crate_config(matches: &getopts::Matches) } } } else { - ErrorOutputType::HumanReadable(color) + match (defaults.error_format, nightly_options::is_nightly_build()) { + (ErrorFormat::Short, true) => ErrorOutputType::Short(color), + _ => ErrorOutputType::HumanReadable(color), + } }; let unparsed_crate_types = matches.opt_strs("crate-type"); @@ -2156,9 +2162,9 @@ mod dep_tracking { #[cfg(test)] mod tests { - use errors; use getopts; use lint; + use errors::{self, EnvDefaults, ColorConfig, ErrorFormat}; use middle::cstore; use session::config::{build_configuration, build_session_options_and_crate_config}; use session::build_session; @@ -2194,7 +2200,11 @@ mod tests { Err(f) => panic!("test_switch_implies_cfg_test: {}", f) }; let registry = errors::registry::Registry::new(&[]); - let (sessopts, cfg) = build_session_options_and_crate_config(matches); + let defaults = EnvDefaults { + error_format: ErrorFormat::Regular, + color: ColorConfig::Auto, + }; + let (sessopts, cfg) = build_session_options_and_crate_config(&matches, defaults); let sess = build_session(sessopts, None, registry); let cfg = build_configuration(&sess, cfg); assert!(cfg.contains(&(Symbol::intern("test"), None))); @@ -2212,7 +2222,11 @@ mod tests { } }; let registry = errors::registry::Registry::new(&[]); - let (sessopts, cfg) = build_session_options_and_crate_config(matches); + let defaults = EnvDefaults { + error_format: ErrorFormat::Regular, + color: ColorConfig::Auto, + }; + let (sessopts, cfg) = build_session_options_and_crate_config(&matches, defaults); let sess = build_session(sessopts, None, registry); let cfg = build_configuration(&sess, cfg); let mut test_items = cfg.iter().filter(|&&(name, _)| name == "test"); @@ -2227,7 +2241,11 @@ mod tests { "-Awarnings".to_string() ]).unwrap(); let registry = errors::registry::Registry::new(&[]); - let (sessopts, _) = build_session_options_and_crate_config(&matches); + let defaults = EnvDefaults { + error_format: ErrorFormat::Regular, + color: ColorConfig::Auto, + }; + let (sessopts, _) = build_session_options_and_crate_config(&matches, defaults); let sess = build_session(sessopts, None, registry); assert!(!sess.diagnostic().flags.can_emit_warnings); } @@ -2238,7 +2256,11 @@ mod tests { "-Dwarnings".to_string() ]).unwrap(); let registry = errors::registry::Registry::new(&[]); - let (sessopts, _) = build_session_options_and_crate_config(&matches); + let defaults = EnvDefaults { + error_format: ErrorFormat::Regular, + color: ColorConfig::Auto, + }; + let (sessopts, _) = build_session_options_and_crate_config(&matches, defaults); let sess = build_session(sessopts, None, registry); assert!(sess.diagnostic().flags.can_emit_warnings); } @@ -2248,7 +2270,11 @@ mod tests { "-Adead_code".to_string() ]).unwrap(); let registry = errors::registry::Registry::new(&[]); - let (sessopts, _) = build_session_options_and_crate_config(&matches); + let defaults = EnvDefaults { + error_format: ErrorFormat::Regular, + color: ColorConfig::Auto, + }; + let (sessopts, _) = build_session_options_and_crate_config(&matches, defaults); let sess = build_session(sessopts, None, registry); assert!(sess.diagnostic().flags.can_emit_warnings); } diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 5fa823659287a..f7a96492ad7a7 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -99,6 +99,7 @@ use syntax::codemap::{CodeMap, FileLoader, RealFileLoader}; use syntax::feature_gate::{GatedCfg, UnstableFeatures}; use syntax::parse::{self, PResult}; use syntax_pos::{DUMMY_SP, MultiSpan, FileName}; +use errors::{EnvDefaults, FromEnv}; #[cfg(test)] mod test; @@ -203,7 +204,8 @@ pub fn run_compiler<'a>(args: &[String], None => return (Ok(()), None), }; - let (sopts, cfg) = config::build_session_options_and_crate_config(&matches); + let defaults = EnvDefaults::from_env(); + let (sopts, cfg) = config::build_session_options_and_crate_config(&matches, defaults); if sopts.debugging_opts.debug_llvm { rustc_trans::enable_llvm_debug(); diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs index af556c576c035..b9b9b368182ce 100644 --- a/src/librustc_errors/emitter.rs +++ b/src/librustc_errors/emitter.rs @@ -17,12 +17,14 @@ use snippet::{Annotation, AnnotationType, Line, MultilineAnnotation, StyledStrin use styled_buffer::StyledBuffer; use std::borrow::Cow; +use std::env; use std::io::prelude::*; use std::io; use std::rc::Rc; use term; use std::collections::HashMap; use std::cmp::min; +use std::str::FromStr; use unicode_width; /// Emitter trait for emitting errors. @@ -85,6 +87,51 @@ pub const MAX_HIGHLIGHT_LINES: usize = 6; /// Arbitrary, but taken from trait import suggestion limit pub const MAX_SUGGESTIONS: usize = 4; +#[derive(Debug)] +pub struct EnvDefaults { + pub error_format: ErrorFormat, + pub color: ColorConfig, +} + +pub trait FromEnv { + fn from_env() -> Self; +} + +impl FromEnv for EnvDefaults { + fn from_env() -> EnvDefaults { + EnvDefaults { + error_format: ErrorFormat::from_env(), + color: ColorConfig::from_env(), + } + } +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum ErrorFormat { + Regular, + Short, +} + +impl FromEnv for ErrorFormat { + fn from_env() -> ErrorFormat { + env::var("RUSTC_ERROR_FORMAT") + .map(|s| ErrorFormat::from_str(&s).expect( + "invalid error format in environment variable `RUSTC_ERROR_FORMAT`")) + .unwrap_or(ErrorFormat::Regular) + } +} + +impl FromStr for ErrorFormat { + type Err = String; + fn from_str(s: &str) -> Result { + match s { + "" | "regular" => Ok(ErrorFormat::Regular), + "short" => Ok(ErrorFormat::Short), + _ => Err(s.into()), + } + } +} + #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub enum ColorConfig { Auto, @@ -102,6 +149,27 @@ impl ColorConfig { } } +impl FromEnv for ColorConfig { + fn from_env() -> ColorConfig { + env::var("RUSTC_COLOR") + .map(|s| ColorConfig::from_str(&s).expect( + "invalid color configuration in environment variable `RUSTC_COLOR`")) + .unwrap_or(ColorConfig::Auto) + } +} + +impl FromStr for ColorConfig { + type Err = String; + fn from_str(s: &str) -> Result { + match s { + "" | "auto" => Ok(ColorConfig::Auto), + "1" | "always" => Ok(ColorConfig::Always), + "never" => Ok(ColorConfig::Never), + _ => Err(s.into()), + } + } +} + pub struct EmitterWriter { dst: Destination, cm: Option>, diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs index 2ac49958d3c53..ff61de9ab7e64 100644 --- a/src/librustc_errors/lib.rs +++ b/src/librustc_errors/lib.rs @@ -28,7 +28,7 @@ extern crate serialize as rustc_serialize; extern crate syntax_pos; extern crate unicode_width; -pub use emitter::ColorConfig; +pub use emitter::{ColorConfig, ErrorFormat, EnvDefaults, FromEnv}; use self::Level::*;