Skip to content

Commit

Permalink
fix: Internal consistency in console output format
Browse files Browse the repository at this point in the history
  • Loading branch information
pvshvp-oss committed May 11, 2024
1 parent d19f754 commit 70081d7
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 76 deletions.
32 changes: 23 additions & 9 deletions paxy/src/app/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -198,20 +198,28 @@ impl Config {
/// Merge configuration values from the CLI
/// These are not set to be optional, so only action-required states are
/// merged with the configuration
pub fn with_overriding_args<A: ui::GlobalArguments>(&mut self, console_arguments: A) -> &mut Self {
pub fn with_overriding_args<A: ui::GlobalArguments>(
&mut self,
console_arguments: A,
) -> &mut Self {
// Incorporate the extra config file specified through arguments
if let Some(path) = console_arguments.config_filepath() {
self.figment = self
.figment
.admerge(("config_filepaths", path));
}

// Override console output mode from console arguments only if a
// non-regular output mode is explicitly specified
let console_output_mode = console_arguments.console_output_mode();
if console_output_mode != ConsoleOutputMode::Regular {
self.figment = self
.figment
.admerge(("console_output_format.mode", console_output_mode));
}

// Override max verbosity from console arguments only if a greater
// output verbosity is explicitly specified
let current_max_verbosity = self
.figment
.extract_inner::<log::LevelFilter>("console_output_format.max_verbosity");
Expand All @@ -227,8 +235,12 @@ impl Config {
}
}

let requested_no_color =
console_arguments.is_no_color() || console_arguments.is_plain() || console_arguments.is_json();
// Override no-color only if no-color is not already enabled and if
// either the environment or the console arguments indicate either
// directly or indirectly that no-color is to be enabled
let requested_no_color = console_arguments.is_no_color()
|| console_arguments.is_plain()
|| console_arguments.is_json();
let current_no_color = self
.figment
.extract_inner::<bool>("console_output_format.no_color");
Expand All @@ -239,24 +251,26 @@ impl Config {
))
.is_ok()
|| env::var("TERM").is_ok_and(|env_term_value| env_term_value.to_lowercase == "dumb");
if (requested_no_color || env_no_color) && !current_no_color.unwrap_or(false) {
if (requested_no_color || env_no_color) && !current_no_color.unwrap_or(false) {
self.figment = self
.figment
.admerge(("console_output_format.no_color", true));
}

self
}

pub fn object(&self) -> Result<ConfigTemplate, Error> {
let config_object = self.figment
let mut config_object = self
.figment
.extract()
.context(ExtractConfigSnafu {})?;

let current_max_verbosity = config_object


config_object
.console_output_format
.internally_consistent();

Ok(config_object)
}
}

Expand Down
73 changes: 8 additions & 65 deletions paxy/src/app/logging.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
pub fn init_log(
console_output_format: &ui::ConsoleOutputFormat,
) -> Result<(Handle, PathBuf), Error> {
pub fn init_log(config: &ConfigTemplate) -> Result<(Handle, PathBuf), Error> {
let log_filename = format!("{}.log", *app::APP_NAME);
let log_dirpath = obtain_log_dirpath(preferred_log_dirpath)?;
let log_dirpath = obtain_log_dirpath(config.log_dirpath)?;
let log_file_appender =
tracing_appender::rolling::daily(log_dirpath.clone(), log_filename.clone());
let log_level_filter = tracing_level_filter_from_log_level_filter(max_output_verbosity);
let log_level_filter = tracing_level_filter_from_log_level_filter(
config
.console_output_format
.max_verbosity,
);

// Obtain writers to various logging destinations and worker guards (for
// keeping the streams alive)
Expand Down Expand Up @@ -154,65 +156,6 @@ pub fn init_log(
))
}

fn resolve_max_output_verbosity(
console_output_format: &ui::ConsoleOutputFormat,
) -> log::LevelFilter {
let verbosity_flag_filter = console_output_format.max_verbosity;

if matches!(
console_output_format.mode,
&ui::ConsoleOutputMode::Plain | &ui::ConsoleOutputMode::Json
) {
return Some(log::LevelFilter::Info);
} else if verbosity_flag_filter < clap_verbosity_flag::LevelFilter::Debug
&& cli_global_arguments.is_debug()
{
return Some(LevelFilter::Debug);
} else {
return verbosity_flag_filter
.as_str()
.parse()
.ok();
}
}

fn adjust_output_formatting(
cli_output_format: &CliOutputFormat,
mut logging_handle: &logging::Handle,
) {
// Turn off colors if requested
if matches!(
cli_output_format.mode,
CliOutputMode::Plain | CliOutputMode::Json
) || cli_output_format.no_color
|| is_env_variable_set("NO_COLOR")
|| is_env_variable_set(format!(
"{}_NO_COLOR",
String::from(*app::APP_NAME).to_uppercase()
))
{
anstream::ColorChoice::Never.write_global();
owo_colors::set_override(false);
}

// Change output mode if requested
match cli_output_format.mode {
CliOutputMode::Plain => logging_handle
.switch_to_plain()
.context(app::LoggingSnafu {})
.context(crate::AppSnafu {})?,
CliOutputMode::Json => logging_handle
.switch_to_json()
.context(app::LoggingSnafu {})
.context(crate::AppSnafu {})?,
CliOutputMode::Test => logging_handle
.switch_to_test()
.context(app::LoggingSnafu {})
.context(crate::AppSnafu {})?,
_ => {}
}
}

fn obtain_log_dirpath(preferred_log_dirpath: Option<PathBuf>) -> Result<PathBuf, Error> {
let obtain_fallback_log_dirpath = || {
let xdg_app_dirs =
Expand Down Expand Up @@ -383,7 +326,7 @@ use tracing_subscriber::{
Layer,
};

use super::ui;
use super::{config::ConfigTemplate, ui};
use crate::app;

// endregion: IMPORTS
78 changes: 76 additions & 2 deletions paxy/src/app/ui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@ where
.context(crate::AppSnafu)?;

// Begin logging
let (mut logging_handle, log_filepath) = logging::init_log(console_input)
let (mut logging_handle, log_filepath) = logging::init_log(&config)
.context(app::LoggingSnafu {})
.context(crate::AppSnafu {})?;

// Adjust output formatting if requested
adjust_output_formatting(&config.cli_output_format, &logging_handle);
adjust_output_formatting(&config.console_output_format, &logging_handle);

emit_welcome_messages();

Expand Down Expand Up @@ -124,6 +124,34 @@ fn emit_test_messages() {
tracing::info!(target:"PLAIN", "{} Testing: Plain Target", console::Emoji("🧪", ""));
}

fn adjust_output_formatting(
internally_consistent_console_output_format: &ConsoleOutputFormat,
mut logging_handle: &logging::Handle,
) {
// Turn off colors if requested
if internally_consistent_console_output_format.no_color {
anstream::ColorChoice::Never.write_global();
owo_colors::set_override(false);
}

// Change output mode if requested
match internally_consistent_console_output_format.mode {
&ConsoleOutputMode::Plain => logging_handle
.switch_to_plain()
.context(app::LoggingSnafu {})
.context(crate::AppSnafu {})?,
&ConsoleOutputMode::Json => logging_handle
.switch_to_json()
.context(app::LoggingSnafu {})
.context(crate::AppSnafu {})?,
&ConsoleOutputMode::Test => logging_handle
.switch_to_test()
.context(app::LoggingSnafu {})
.context(crate::AppSnafu {})?,
_ => {}
}
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ConsoleOutputFormat {
pub mode: ConsoleOutputMode,
Expand All @@ -141,6 +169,52 @@ impl Default for ConsoleOutputFormat {
}
}

impl ConsoleOutputFormat {
/// Make the console output format internally consistent.
/// 1. Adjust the no-color setting to be consistent with the console output
/// mode - there should be no color in plain and json modes.
/// 2. Adjust the max verbosity to be consistent with the console output
/// mode - decrease the max verbosity if in plain or json modes.
pub fn internally_consistent(&mut self) -> &self {
self.internally_consistent_color();
self.internally_consistent_verbosity();

self
}

/// Adjust the no-color setting to be consistent with the console output
/// mode - there should be no color in plain and json modes.
/// If color is already disabled, do not enable it. Otherwise toggle
/// no-color based on the console output mode.
fn internally_consistent_color(&mut self) {
if !no_color
&& matches!(
self.mode,
ConsoleOutputMode::Plain | ConsoleOutputMode::Json
)
{
self.no_color = false;
}

self
}

/// Adjust the max verbosity to be consistent with the console output
/// mode - decrease the max verbosity if in plain or json modes.
fn internally_consistent_verbosity(&mut self) {
if self.max_verbosity > log::LevelFilter::Info
&& matches!(
self.mode,
ConsoleOutputMode::Plain | ConsoleOutputMode::Json
)
{
self.max_verbosity = log::LevelFilter::Info;
}

self
}
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum ConsoleOutputMode {
Regular,
Expand Down

0 comments on commit 70081d7

Please sign in to comment.