fix: log config file logs after reading config files (#961)

This commit is contained in:
aawsome 2023-12-03 23:19:02 +01:00 committed by GitHub
parent ae25e39bd5
commit 536d1c1fac
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 79 additions and 60 deletions

View File

@ -1,17 +1,14 @@
//! Rustic Abscissa Application
use std::env;
use std::fs::File;
use std::str::FromStr;
use abscissa_core::{
application::{self, AppCell},
config::{self, CfgCell},
terminal::{component::Terminal, ColorChoice},
Application, Component, FrameworkError, FrameworkErrorKind, StandardPaths,
terminal::component::Terminal,
Application, Component, FrameworkError, StandardPaths,
};
use anyhow::Result;
use simplelog::{CombinedLogger, LevelFilter, TermLogger, TerminalMode, WriteLogger};
// use crate::helpers::*;
use crate::{commands::EntryPoint, config::RusticConfig};
@ -98,41 +95,6 @@ impl Application for RusticApp {
env::set_var(env, value);
}
// start logger
let level_filter = match &config.global.log_level {
Some(level) => LevelFilter::from_str(level)
.map_err(|e| FrameworkErrorKind::ConfigError.context(e))?,
None => LevelFilter::Info,
};
match &config.global.log_file {
None => TermLogger::init(
level_filter,
simplelog::ConfigBuilder::new()
.set_time_level(LevelFilter::Off)
.build(),
TerminalMode::Stderr,
ColorChoice::Auto,
)
.map_err(|e| FrameworkErrorKind::ConfigError.context(e))?,
Some(file) => CombinedLogger::init(vec![
TermLogger::new(
level_filter.min(LevelFilter::Warn),
simplelog::ConfigBuilder::new()
.set_time_level(LevelFilter::Off)
.build(),
TerminalMode::Stderr,
ColorChoice::Auto,
),
WriteLogger::new(
level_filter,
simplelog::Config::default(),
File::options().create(true).append(true).open(file)?,
),
])
.map_err(|e| FrameworkErrorKind::ConfigError.context(e))?,
}
self.config.set_once(config);
Ok(())

View File

@ -23,7 +23,9 @@ pub(crate) mod show_config;
pub(crate) mod snapshots;
pub(crate) mod tag;
use std::fs::File;
use std::path::PathBuf;
use std::str::FromStr;
use std::sync::Arc;
use crate::{
@ -38,10 +40,15 @@ use crate::{
{Application, RUSTIC_APP},
};
use abscissa_core::{config::Override, Command, Configurable, FrameworkError, Runnable, Shutdown};
use abscissa_core::{
config::Override, terminal::ColorChoice, Command, Configurable, FrameworkError,
FrameworkErrorKind, Runnable, Shutdown,
};
use anyhow::{anyhow, Result};
use dialoguer::Password;
use log::{log, Level};
use rustic_core::{OpenStatus, Repository};
use simplelog::{CombinedLogger, LevelFilter, TermLogger, TerminalMode, WriteLogger};
pub(super) mod constants {
pub(super) const MAX_PASSWORD_RETRIES: usize = 5;
@ -153,13 +160,57 @@ impl Configurable<RusticConfig> for EntryPoint {
// rustic logic and merged with the CLI options.
// That's why it says `_config`, because it's not read at all and therefore not needed.
let mut config = self.config.clone();
if config.global.use_profile.is_empty() {
config.global.use_profile.push("rustic".to_string());
}
// collect logs during merging as we start the logger *after* merging
let mut merge_logs = Vec::new();
// get global options from command line / env and config file
for profile in &config.global.use_profile.clone() {
config.merge_profile(profile)?;
if config.global.use_profile.is_empty() {
config.merge_profile("rustic", &mut merge_logs, Level::Info)?;
} else {
for profile in &config.global.use_profile.clone() {
config.merge_profile(profile, &mut merge_logs, Level::Warn)?;
}
}
// start logger
let level_filter = match &config.global.log_level {
Some(level) => LevelFilter::from_str(level)
.map_err(|e| FrameworkErrorKind::ConfigError.context(e))?,
None => LevelFilter::Info,
};
match &config.global.log_file {
None => TermLogger::init(
level_filter,
simplelog::ConfigBuilder::new()
.set_time_level(LevelFilter::Off)
.build(),
TerminalMode::Stderr,
ColorChoice::Auto,
)
.map_err(|e| FrameworkErrorKind::ConfigError.context(e))?,
Some(file) => CombinedLogger::init(vec![
TermLogger::new(
level_filter.min(LevelFilter::Warn),
simplelog::ConfigBuilder::new()
.set_time_level(LevelFilter::Off)
.build(),
TerminalMode::Stderr,
ColorChoice::Auto,
),
WriteLogger::new(
level_filter,
simplelog::Config::default(),
File::options().create(true).append(true).open(file)?,
),
])
.map_err(|e| FrameworkErrorKind::ConfigError.context(e))?,
}
// display logs from merging
for (level, merge_log) in merge_logs {
log!(level, "{}", merge_log);
}
match &self.commands {

View File

@ -17,6 +17,7 @@ use abscissa_core::path::AbsPathBuf;
use abscissa_core::FrameworkError;
use clap::Parser;
use itertools::Itertools;
use log::Level;
use rustic_core::RepositoryOptions;
use serde::{Deserialize, Serialize};
@ -61,35 +62,40 @@ pub struct RusticConfig {
}
impl RusticConfig {
/// Merge a profile into the current config
/// Merge a profile into the current config by reading the corresponding config file.
/// Also recursively merge all profiles given within this config file.
///
/// # Arguments
///
/// * `profile` - name of the profile to merge
///
// TODO!: Explain more
pub fn merge_profile(&mut self, profile: &str) -> Result<(), FrameworkError> {
/// * `merge_logs` - Vector to collect logs during merging
/// * `level_missing` - The log level to use if this profile is missing. Recursive calls will produce a Warning.
pub fn merge_profile(
&mut self,
profile: &str,
merge_logs: &mut Vec<(Level, String)>,
level_missing: Level,
) -> Result<(), FrameworkError> {
let profile_filename = profile.to_string() + ".toml";
let paths = get_config_paths(&profile_filename);
if let Some(path) = paths.iter().find(|path| path.exists()) {
// TODO: This should be log::info! - however, the logging config
// can be stored in the config file and is needed to initialize the logger
eprintln!("using config {}", path.display());
merge_logs.push((Level::Info, format!("using config {}", path.display())));
let mut config = Self::load_toml_file(AbsPathBuf::canonicalize(path)?)?;
// if "use_profile" is defined in config file, merge the referenced profiles first
for profile in &config.global.use_profile.clone() {
config.merge_profile(profile)?;
config.merge_profile(profile, merge_logs, Level::Warn)?;
}
self.merge(config);
} else {
let paths_string = paths.iter().map(|path| path.display()).join(", ");
// TODO: This should be log::warn! - however, the logging config
// can be stored in the config file and is needed to initialize the logger
eprintln!(
"using no config file, none of these exist: {}",
&paths_string
);
merge_logs.push((
level_missing,
format!(
"using no config file, none of these exist: {}",
&paths_string
),
));
};
Ok(())
}