pub mod actions;
pub mod app;
pub mod color_depth;
pub mod components;
pub mod display_columns;
pub mod events;
pub mod headless;
pub mod json_output;
pub mod positional;
pub mod screenshot;
pub mod theme;
pub mod ui;
pub mod widgets;
use anyhow::{Context, Result};
use std::path::PathBuf;
use tracing_subscriber::{EnvFilter, Layer, fmt, prelude::*};
pub const ISSUE_TRACKER_URL: &str = "https://github.com/ivankovic/omnidiff/issues";
pub const LOG_ENV: &str = "RUST_LOG";
pub fn initialize_logging() -> Result<()> {
if std::env::var_os(LOG_ENV).is_none_or(|value| value.is_empty()) {
return Ok(());
}
let path = log_file_path();
if let Some(directory) = path.parent() {
std::fs::create_dir_all(directory)
.with_context(|| format!("failed to create {}", directory.display()))?;
}
let log_file = std::fs::File::create(&path)
.with_context(|| format!("failed to create the log file {}", path.display()))?;
let env_filter = EnvFilter::builder()
.with_default_directive(tracing::Level::INFO.into())
.from_env_lossy();
let file_subscriber = fmt::layer()
.with_file(true)
.with_line_number(true)
.with_writer(log_file)
.with_target(false)
.with_ansi(false)
.with_filter(env_filter);
tracing_subscriber::registry()
.with(file_subscriber)
.with(tracing_error::ErrorLayer::default())
.try_init()?;
Ok(())
}
pub fn log_file_path() -> PathBuf {
log_file_path_from(
std::env::var_os("XDG_STATE_HOME").map(PathBuf::from),
std::env::var_os("HOME").map(PathBuf::from),
std::env::temp_dir(),
)
}
fn log_file_path_from(
xdg_state_home: Option<PathBuf>,
home: Option<PathBuf>,
temp_dir: PathBuf,
) -> PathBuf {
let base = match (xdg_state_home, home) {
(Some(xdg), _) if !xdg.as_os_str().is_empty() => xdg,
(_, Some(home)) if !home.as_os_str().is_empty() => home.join(".local").join("state"),
_ => temp_dir,
};
base.join("omnidiff").join("log.txt")
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn log_file_prefers_xdg_state_home_then_home_then_the_temp_dir() {
let temp = PathBuf::from("/tmp");
assert_eq!(
log_file_path_from(Some("/xdg".into()), Some("/home/u".into()), temp.clone()),
PathBuf::from("/xdg/omnidiff/log.txt")
);
assert_eq!(
log_file_path_from(None, Some("/home/u".into()), temp.clone()),
PathBuf::from("/home/u/.local/state/omnidiff/log.txt")
);
assert_eq!(
log_file_path_from(Some("".into()), Some("".into()), temp),
PathBuf::from("/tmp/omnidiff/log.txt")
);
}
}