From ca1527938658cd2abbd4b75a58509fc7f9a8541f Mon Sep 17 00:00:00 2001 From: Danilo Bargen Date: Sat, 30 Jan 2021 21:55:28 +0100 Subject: [PATCH] Show reason for choice of a certain cache/config dir --- src/cache.rs | 19 ++++++++++--------- src/config.rs | 17 +++++++++-------- src/main.rs | 39 ++++++++++++++++++++++++--------------- src/types.rs | 27 ++++++++++++++++++++++++++- tests/lib.rs | 7 ++++++- 5 files changed, 75 insertions(+), 34 deletions(-) diff --git a/src/cache.rs b/src/cache.rs index 802c06e..961fd0c 100644 --- a/src/cache.rs +++ b/src/cache.rs @@ -13,7 +13,7 @@ use tar::Archive; use walkdir::{DirEntry, WalkDir}; use crate::error::TealdeerError::{self, CacheError, UpdateError}; -use crate::types::OsType; +use crate::types::{OsType, PathSource}; #[derive(Debug)] pub struct Cache { @@ -33,14 +33,14 @@ impl Cache { } /// Return the path to the cache directory. - pub fn get_cache_dir() -> Result { + pub fn get_cache_dir() -> Result<(PathBuf, PathSource), TealdeerError> { // Allow overriding the cache directory by setting the // $TEALDEER_CACHE_DIR env variable. if let Ok(value) = env::var("TEALDEER_CACHE_DIR") { let path = PathBuf::from(value); if path.exists() && path.is_dir() { - return Ok(path); + return Ok((path, PathSource::EnvVar)); } else { return Err(CacheError( "Path specified by $TEALDEER_CACHE_DIR \ @@ -52,7 +52,7 @@ impl Cache { // Otherwise, fall back to user cache directory. match get_app_root(AppDataType::UserCache, &crate::APP_INFO) { - Ok(dirs) => Ok(dirs), + Ok(dirs) => Ok((dirs, PathSource::OsConvention)), Err(_) => Err(CacheError( "Could not determine user cache directory.".into(), )), @@ -94,7 +94,7 @@ impl Cache { let mut archive = Self::decompress(&bytes[..]); // Determine paths - let cache_dir = Self::get_cache_dir()?; + let (cache_dir, _) = Self::get_cache_dir()?; // Make sure that cache directory exists debug!("Ensure cache directory {:?} exists", &cache_dir); @@ -119,7 +119,7 @@ impl Cache { /// Return the duration since the cache directory was last modified. pub fn last_update() -> Option { - if let Ok(cache_dir) = Self::get_cache_dir() { + if let Ok((cache_dir, _)) = Self::get_cache_dir() { if let Ok(metadata) = fs::metadata(cache_dir.join("tldr-master")) { if let Ok(mtime) = metadata.modified() { let now = SystemTime::now(); @@ -161,7 +161,7 @@ impl Cache { // Get cache dir let cache_dir = match Self::get_cache_dir() { - Ok(cache_dir) => cache_dir.join("tldr-master"), + Ok((cache_dir, _)) => cache_dir.join("tldr-master"), Err(e) => { log::error!("Could not get cache directory: {}", e); return None; @@ -194,7 +194,7 @@ impl Cache { /// Return the available pages. pub fn list_pages(&self) -> Result, TealdeerError> { // Determine platforms directory and platform - let cache_dir = Self::get_cache_dir()?; + let (cache_dir, _) = Self::get_cache_dir()?; let platforms_dir = cache_dir.join("tldr-master").join("pages"); let platform_dir = self.get_platform_dir(); @@ -242,8 +242,9 @@ impl Cache { } /// Delete the cache directory. + #[allow(clippy::map_err_ignore)] pub fn clear() -> Result<(), TealdeerError> { - let path = Self::get_cache_dir()?; + let (path, _) = Self::get_cache_dir()?; if path.exists() && path.is_dir() { fs::remove_dir_all(&path).map_err(|_| { CacheError(format!( diff --git a/src/config.rs b/src/config.rs index 302846f..447725b 100644 --- a/src/config.rs +++ b/src/config.rs @@ -10,6 +10,7 @@ use log::debug; use serde_derive::{Deserialize, Serialize}; use crate::error::TealdeerError::{self, ConfigError}; +use crate::types::PathSource; pub const CONFIG_FILE_NAME: &str = "config.toml"; pub const MAX_CACHE_AGE: Duration = Duration::from_secs(2_592_000); // 30 days @@ -234,7 +235,7 @@ impl Config { debug!("Loading config"); // Determine path - let config_file_path = get_config_path() + let (config_file_path, _) = get_config_path() .map_err(|e| ConfigError(format!("Could not determine config path: {}", e)))?; // Load raw config @@ -276,16 +277,16 @@ impl Config { /// /// Note that this function does not verify whether the directory at that /// location exists, or is a directory. -pub fn get_config_dir() -> Result { +pub fn get_config_dir() -> Result<(PathBuf, PathSource), TealdeerError> { // Allow overriding the config directory by setting the // $TEALDEER_CONFIG_DIR env variable. if let Ok(value) = env::var("TEALDEER_CONFIG_DIR") { - return Ok(PathBuf::from(value)); + return Ok((PathBuf::from(value), PathSource::EnvVar)); }; // Otherwise, fall back to the user config directory. match get_app_root(AppDataType::UserConfig, &crate::APP_INFO) { - Ok(dirs) => Ok(dirs), + Ok(dirs) => Ok((dirs, PathSource::OsConvention)), Err(_) => Err(ConfigError( "Could not determine the user config directory.".into(), )), @@ -296,15 +297,15 @@ pub fn get_config_dir() -> Result { /// /// Note that this function does not verify whether the file at that location /// exists, or is a file. -pub fn get_config_path() -> Result { - let config_dir = get_config_dir()?; +pub fn get_config_path() -> Result<(PathBuf, PathSource), TealdeerError> { + let (config_dir, source) = get_config_dir()?; let config_file_path = config_dir.join(CONFIG_FILE_NAME); - Ok(config_file_path) + Ok((config_file_path, source)) } /// Create default config file. pub fn make_default_config() -> Result { - let config_dir = get_config_dir()?; + let (config_dir, _) = get_config_dir()?; // Ensure that config directory exists if !config_dir.exists() { diff --git a/src/main.rs b/src/main.rs index 94d6506..b32acd7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -183,7 +183,7 @@ fn update_cache(cache: &Cache, quietly: bool) { /// Show the config path (DEPRECATED) fn show_config_path() { match get_config_path() { - Ok(config_file_path) => { + Ok((config_file_path, _)) => { println!("Config path is: {}", config_file_path.to_str().unwrap()); } Err(ConfigError(msg)) => { @@ -199,23 +199,32 @@ fn show_config_path() { /// Show file paths fn show_paths() { - let config_dir = get_config_dir() - .map(|mut path| { + let config_dir = get_config_dir().map_or_else( + |e| format!("[Error: {}]", e), + |(mut path, source)| { path.push(""); // Trailing path separator - path.to_str().unwrap_or("[Invalid]").to_string() - }) - .unwrap_or_else(|e| format!("[Error: {}]", e)); - let config_path = get_config_path() - .map(|path| path.to_str().unwrap_or("[Invalid]").to_string()) - .unwrap_or_else(|e| format!("[Error: {}]", e)); - let cache_dir = Cache::get_cache_dir() - .map(|mut path| { + match path.to_str() { + Some(path) => format!("{} ({})", path, source), + None => "[Invalid]".to_string(), + } + }, + ); + let config_path = get_config_path().map_or_else( + |e| format!("[Error: {}]", e), + |(path, _)| path.to_str().unwrap_or("[Invalid]").to_string(), + ); + let cache_dir = Cache::get_cache_dir().map_or_else( + |e| format!("[Error: {}]", e), + |(mut path, source)| { path.push(""); // Trailing path separator - path.to_str().unwrap_or("[Invalid]").to_string() - }) - .unwrap_or_else(|e| format!("[Error: {}]", e)); + match path.to_str() { + Some(path) => format!("{} ({})", path, source), + None => "[Invalid]".to_string(), + } + }, + ); let pages_dir = Cache::get_cache_dir() - .map(|path| path.join("tldr-master")) + .map(|(path, _)| path.join("tldr-master")) .map(|mut path| { path.push(""); // Trailing path separator path.to_str().unwrap_or("[Invalid]").to_string() diff --git a/src/types.rs b/src/types.rs index c0dfb27..c68dba8 100644 --- a/src/types.rs +++ b/src/types.rs @@ -1,4 +1,4 @@ -//! Types used in the client. +//! Shared types used in tealdeer. use std::fmt; @@ -101,6 +101,31 @@ impl LineType { } } +/// The reason why a certain path (e.g. config path or cache dir) was chosen. +#[derive(Debug, PartialEq)] +pub enum PathSource { + /// OS convention (e.g. XDG on Linux) + OsConvention, + /// Env variable (TEALDEER_*) + EnvVar, + /// Config file variable + ConfigVar, +} + +impl fmt::Display for PathSource { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!( + f, + "{}", + match self { + Self::OsConvention => "OS convention", + Self::EnvVar => "env variable", + Self::ConfigVar => "config file variable", + } + ) + } +} + #[cfg(test)] mod test { use super::LineType; diff --git a/tests/lib.rs b/tests/lib.rs index d880584..7f7ad4c 100644 --- a/tests/lib.rs +++ b/tests/lib.rs @@ -229,7 +229,12 @@ fn test_show_paths() { ))) .stdout(contains(format!( "Pages dir: {}", - testenv.cache_dir.path().join("tldr-master").to_str().unwrap(), + testenv + .cache_dir + .path() + .join("tldr-master") + .to_str() + .unwrap(), ))); }