From 6152d15e7c06910a3fe1e7621f624ceaa9d010a8 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Mon, 3 Jan 2022 16:32:52 -0800 Subject: [PATCH] Extract init_env_logger to crate --- Cargo.lock | 14 ++++-- compiler/rustc_driver/Cargo.toml | 6 +-- compiler/rustc_driver/src/lib.rs | 57 +++-------------------- compiler/rustc_log/Cargo.toml | 16 +++++++ compiler/rustc_log/src/lib.rs | 78 ++++++++++++++++++++++++++++++++ 5 files changed, 114 insertions(+), 57 deletions(-) create mode 100644 compiler/rustc_log/Cargo.toml create mode 100644 compiler/rustc_log/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index a912eee97db..17f7d2ca15a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3808,7 +3808,6 @@ dependencies = [ name = "rustc_driver" version = "0.0.0" dependencies = [ - "atty", "libc", "rustc_ast", "rustc_ast_pretty", @@ -3822,6 +3821,7 @@ dependencies = [ "rustc_hir_pretty", "rustc_interface", "rustc_lint", + "rustc_log", "rustc_metadata", "rustc_middle", "rustc_parse", @@ -3833,8 +3833,6 @@ dependencies = [ "rustc_target", "rustc_typeck", "tracing", - "tracing-subscriber", - "tracing-tree", "winapi", ] @@ -4077,6 +4075,16 @@ dependencies = [ "libc", ] +[[package]] +name = "rustc_log" +version = "0.0.0" +dependencies = [ + "atty", + "tracing", + "tracing-subscriber", + "tracing-tree", +] + [[package]] name = "rustc_macros" version = "0.1.0" diff --git a/compiler/rustc_driver/Cargo.toml b/compiler/rustc_driver/Cargo.toml index 2383a000687..872f946bf7d 100644 --- a/compiler/rustc_driver/Cargo.toml +++ b/compiler/rustc_driver/Cargo.toml @@ -8,10 +8,8 @@ crate-type = ["dylib"] [dependencies] libc = "0.2" -atty = "0.2" tracing = { version = "0.1.28" } -tracing-subscriber = { version = "0.3.3", default-features = false, features = ["fmt", "env-filter", "smallvec", "parking_lot", "ansi"] } -tracing-tree = "0.2.0" +rustc_log = { path = "../rustc_log" } rustc_middle = { path = "../rustc_middle" } rustc_ast_pretty = { path = "../rustc_ast_pretty" } rustc_target = { path = "../rustc_target" } @@ -40,4 +38,4 @@ winapi = { version = "0.3", features = ["consoleapi", "debugapi", "processenv"] [features] llvm = ['rustc_interface/llvm'] -max_level_info = ['tracing/max_level_info'] +max_level_info = ['rustc_log/max_level_info'] diff --git a/compiler/rustc_driver/src/lib.rs b/compiler/rustc_driver/src/lib.rs index 12e0b7a4977..3d58b27f839 100644 --- a/compiler/rustc_driver/src/lib.rs +++ b/compiler/rustc_driver/src/lib.rs @@ -24,6 +24,7 @@ use rustc_feature::find_gated_cfg; use rustc_interface::util::{self, collect_crate_types, get_codegen_backend}; use rustc_interface::{interface, Queries}; use rustc_lint::LintStore; +use rustc_log::stdout_isatty; use rustc_metadata::locator; use rustc_save_analysis as save; use rustc_save_analysis::DumpHandler; @@ -514,14 +515,6 @@ impl Compilation { #[derive(Copy, Clone)] pub struct RustcDefaultCalls; -fn stdout_isatty() -> bool { - atty::is(atty::Stream::Stdout) -} - -fn stderr_isatty() -> bool { - atty::is(atty::Stream::Stderr) -} - fn handle_explain(registry: Registry, code: &str, output: ErrorOutputType) { let upper_cased_code = code.to_ascii_uppercase(); let normalised = if upper_cased_code.starts_with('E') { @@ -1254,54 +1247,18 @@ pub fn install_ice_hook() { /// This allows tools to enable rust logging without having to magically match rustc's /// tracing crate version. pub fn init_rustc_env_logger() { - init_env_logger("RUSTC_LOG") + if let Err(error) = rustc_log::init_rustc_env_logger() { + early_error(ErrorOutputType::default(), &error.to_string()); + } } /// This allows tools to enable rust logging without having to magically match rustc's /// tracing crate version. In contrast to `init_rustc_env_logger` it allows you to choose an env var /// other than `RUSTC_LOG`. pub fn init_env_logger(env: &str) { - use tracing_subscriber::{ - filter::{self, EnvFilter, LevelFilter}, - layer::SubscriberExt, - }; - - let filter = match std::env::var(env) { - Ok(env) => EnvFilter::new(env), - _ => EnvFilter::default().add_directive(filter::Directive::from(LevelFilter::WARN)), - }; - - let color_logs = match std::env::var(String::from(env) + "_COLOR") { - Ok(value) => match value.as_ref() { - "always" => true, - "never" => false, - "auto" => stderr_isatty(), - _ => early_error( - ErrorOutputType::default(), - &format!( - "invalid log color value '{}': expected one of always, never, or auto", - value - ), - ), - }, - Err(std::env::VarError::NotPresent) => stderr_isatty(), - Err(std::env::VarError::NotUnicode(_value)) => early_error( - ErrorOutputType::default(), - "non-Unicode log color value: expected one of always, never, or auto", - ), - }; - - let layer = tracing_tree::HierarchicalLayer::default() - .with_writer(io::stderr) - .with_indent_lines(true) - .with_ansi(color_logs) - .with_targets(true) - .with_indent_amount(2); - #[cfg(parallel_compiler)] - let layer = layer.with_thread_ids(true).with_thread_names(true); - - let subscriber = tracing_subscriber::Registry::default().with(filter).with(layer); - tracing::subscriber::set_global_default(subscriber).unwrap(); + if let Err(error) = rustc_log::init_env_logger(env) { + early_error(ErrorOutputType::default(), &error.to_string()); + } } #[cfg(all(unix, any(target_env = "gnu", target_os = "macos")))] diff --git a/compiler/rustc_log/Cargo.toml b/compiler/rustc_log/Cargo.toml new file mode 100644 index 00000000000..5b037946224 --- /dev/null +++ b/compiler/rustc_log/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "rustc_log" +version = "0.0.0" +edition = "2021" + +[lib] +doctest = false + +[dependencies] +atty = "0.2" +tracing = "0.1.28" +tracing-subscriber = { version = "0.3.3", default-features = false, features = ["fmt", "env-filter", "smallvec", "parking_lot", "ansi"] } +tracing-tree = "0.2.0" + +[features] +max_level_info = ['tracing/max_level_info'] diff --git a/compiler/rustc_log/src/lib.rs b/compiler/rustc_log/src/lib.rs new file mode 100644 index 00000000000..498c8cf9c5e --- /dev/null +++ b/compiler/rustc_log/src/lib.rs @@ -0,0 +1,78 @@ +//! This crate allows tools to enable rust logging without having to magically +//! match rustc's tracing crate version. + +use std::env::{self, VarError}; +use std::fmt::{self, Display}; +use std::io; +use tracing_subscriber::filter::{Directive, EnvFilter, LevelFilter}; +use tracing_subscriber::layer::SubscriberExt; + +pub fn init_rustc_env_logger() -> Result<(), Error> { + init_env_logger("RUSTC_LOG") +} + +/// In contrast to `init_rustc_env_logger` this allows you to choose an env var +/// other than `RUSTC_LOG`. +pub fn init_env_logger(env: &str) -> Result<(), Error> { + let filter = match env::var(env) { + Ok(env) => EnvFilter::new(env), + _ => EnvFilter::default().add_directive(Directive::from(LevelFilter::WARN)), + }; + + let color_logs = match env::var(String::from(env) + "_COLOR") { + Ok(value) => match value.as_ref() { + "always" => true, + "never" => false, + "auto" => stderr_isatty(), + _ => return Err(Error::InvalidColorValue(value)), + }, + Err(VarError::NotPresent) => stderr_isatty(), + Err(VarError::NotUnicode(_value)) => return Err(Error::NonUnicodeColorValue), + }; + + let layer = tracing_tree::HierarchicalLayer::default() + .with_writer(io::stderr) + .with_indent_lines(true) + .with_ansi(color_logs) + .with_targets(true) + .with_indent_amount(2); + #[cfg(parallel_compiler)] + let layer = layer.with_thread_ids(true).with_thread_names(true); + + let subscriber = tracing_subscriber::Registry::default().with(filter).with(layer); + tracing::subscriber::set_global_default(subscriber).unwrap(); + + Ok(()) +} + +pub fn stdout_isatty() -> bool { + atty::is(atty::Stream::Stdout) +} + +pub fn stderr_isatty() -> bool { + atty::is(atty::Stream::Stderr) +} + +#[derive(Debug)] +pub enum Error { + InvalidColorValue(String), + NonUnicodeColorValue, +} + +impl std::error::Error for Error {} + +impl Display for Error { + fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Error::InvalidColorValue(value) => write!( + formatter, + "invalid log color value '{}': expected one of always, never, or auto", + value, + ), + Error::NonUnicodeColorValue => write!( + formatter, + "non-Unicode log color value: expected one of always, never, or auto", + ), + } + } +}