From bed34168c15f1936cc1ec708f9927ea32fb31e7a Mon Sep 17 00:00:00 2001 From: teor Date: Tue, 1 Dec 2020 11:09:57 +1000 Subject: [PATCH] Automatically disable abscissa colors and color_eyre when writing to a file --- zebrad/src/application.rs | 56 ++++++++++++++++++++++++++++----------- 1 file changed, 41 insertions(+), 15 deletions(-) diff --git a/zebrad/src/application.rs b/zebrad/src/application.rs index 916ee1e4b..e73f6a56e 100644 --- a/zebrad/src/application.rs +++ b/zebrad/src/application.rs @@ -6,6 +6,7 @@ use abscissa_core::{ config, config::Configurable, terminal::component::Terminal, + terminal::ColorChoice, Application, Component, EntryPoint, FrameworkError, Shutdown, StandardPaths, }; use application::fatal_error; @@ -90,21 +91,24 @@ impl Application for ZebradApp { &mut self, command: &Self::Cmd, ) -> Result>>, FrameworkError> { - let terminal = Terminal::new(self.term_colors(command)); - // This MUST happen after `Terminal::new` to ensure our preferred panic - // handler is the last one installed - color_eyre::config::HookBuilder::default() - .issue_url(concat!(env!("CARGO_PKG_REPOSITORY"), "/issues/new")) - .add_issue_metadata("version", env!("CARGO_PKG_VERSION")) - .add_issue_metadata("git commit", Self::GIT_COMMIT) - .issue_filter(|kind| match kind { - color_eyre::ErrorKind::NonRecoverable(_) => true, - color_eyre::ErrorKind::Recoverable(error) => { - !error.is::() - } - }) - .install() - .unwrap(); + // Automatically use color if we're outputting to a terminal + // + // The `abcissa` docs claim that abscissa implements `Auto`, but it + // does not - except in `color_backtrace` backtraces. + let mut term_colors = self.term_colors(command); + if term_colors == ColorChoice::Auto { + // We want to disable colors on a per-stream basis, but that feature + // can only be implemented inside the terminal component streams. + // Instead, if either output stream is not a terminal, disable + // colors. + // + // We'd also like to check `config.tracing.use_color` here, but the + // config has not been loaded yet. + if !atty::is(atty::Stream::Stdout) || !atty::is(atty::Stream::Stderr) { + term_colors = ColorChoice::Never; + } + } + let terminal = Terminal::new(term_colors); Ok(vec![Box::new(terminal)]) } @@ -129,6 +133,28 @@ impl Application for ZebradApp { .transpose()? .unwrap_or_default(); + // Only use color if tracing output is being sent to a terminal + let use_color = config.tracing.use_color && atty::is(atty::Stream::Stdout); + + // color_eyre always uses color, so disable it if we don't want color + // (color_backtrace automatically disables color if stderr is a file) + if use_color { + // This MUST happen after `Terminal::new` to ensure our preferred panic + // handler is the last one installed + color_eyre::config::HookBuilder::default() + .issue_url(concat!(env!("CARGO_PKG_REPOSITORY"), "/issues/new")) + .add_issue_metadata("version", env!("CARGO_PKG_VERSION")) + .add_issue_metadata("git commit", Self::GIT_COMMIT) + .issue_filter(|kind| match kind { + color_eyre::ErrorKind::NonRecoverable(_) => true, + color_eyre::ErrorKind::Recoverable(error) => { + !error.is::() + } + }) + .install() + .unwrap(); + } + let config = command.process_config(config)?; self.config = Some(config);