Show reason for choice of a certain cache/config dir

This commit is contained in:
Danilo Bargen 2021-01-30 21:55:28 +01:00
commit ca15279386
5 changed files with 75 additions and 34 deletions

View file

@ -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<PathBuf, TealdeerError> {
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<Duration> {
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<Vec<String>, 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!(

View file

@ -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<PathBuf, TealdeerError> {
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<PathBuf, TealdeerError> {
///
/// Note that this function does not verify whether the file at that location
/// exists, or is a file.
pub fn get_config_path() -> Result<PathBuf, TealdeerError> {
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<PathBuf, TealdeerError> {
let config_dir = get_config_dir()?;
let (config_dir, _) = get_config_dir()?;
// Ensure that config directory exists
if !config_dir.exists() {

View file

@ -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()

View file

@ -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;

View file

@ -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(),
)));
}