mirror of
https://github.com/tealdeer-rs/tealdeer.git
synced 2026-08-09 09:49:10 +02:00
Allow overriding cache directory through config
- Config: Add `cache_dir` to `[directories]` section - Logic to handle legacy env var, config override and default cache dir selection is now in the `Config::try_from(RawConfig)` impl - Deprecate old `TEALDEER_CACHE_DIR` env variable - Update docs Co-authored-by: Hans Gaiser <hansg91@gmail.com>
This commit is contained in:
parent
026ae72742
commit
33f0f108d8
5 changed files with 168 additions and 152 deletions
|
|
@ -2,6 +2,19 @@
|
|||
|
||||
This section allows overriding some directory paths.
|
||||
|
||||
## `cache_dir`
|
||||
|
||||
Override the cache directory. Remember to use an absolute path. Variable
|
||||
expansion will not be performed on the path. If the directory does not yet
|
||||
exist, it will be created.
|
||||
|
||||
[directories]
|
||||
cache_dir = "/home/myuser/.tealdeer-cache/"
|
||||
|
||||
If no `cache_dir` is specified, tealdeer will fall back to a location that
|
||||
follows OS conventions. On Linux, it will usually be at `~/.cache/tealdeer/`.
|
||||
Use `tldr --show-paths` to show the path that is being used.
|
||||
|
||||
## `custom_pages_dir`
|
||||
|
||||
Set the directory to be used to look up [custom
|
||||
|
|
|
|||
137
src/cache.rs
137
src/cache.rs
|
|
@ -8,15 +8,12 @@ use std::{
|
|||
};
|
||||
|
||||
use anyhow::{ensure, Context, Result};
|
||||
use app_dirs::{get_app_root, AppDataType};
|
||||
use log::debug;
|
||||
use reqwest::{blocking::Client, Proxy};
|
||||
use walkdir::{DirEntry, WalkDir};
|
||||
use zip::ZipArchive;
|
||||
|
||||
use crate::types::{PathSource, PlatformType};
|
||||
|
||||
static CACHE_DIR_ENV_VAR: &str = "TEALDEER_CACHE_DIR";
|
||||
use crate::types::PlatformType;
|
||||
|
||||
pub static TLDR_PAGES_DIR: &str = "tldr-pages";
|
||||
static TLDR_OLD_PAGES_DIR: &str = "tldr-master";
|
||||
|
|
@ -25,6 +22,7 @@ static TLDR_OLD_PAGES_DIR: &str = "tldr-master";
|
|||
pub struct Cache {
|
||||
url: String,
|
||||
platform: PlatformType,
|
||||
cache_dir: PathBuf,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
|
@ -54,13 +52,13 @@ impl PageLookupResult {
|
|||
pub fn reader(&self) -> Result<BufReader<Box<dyn Read>>> {
|
||||
// Open page file
|
||||
let page_file = File::open(&self.page_path)
|
||||
.with_context(|| format!("Could not open page file at {:?}", self.page_path))?;
|
||||
.with_context(|| format!("Could not open page file at {}", self.page_path.display()))?;
|
||||
|
||||
// Open patch file
|
||||
let patch_file_opt = match &self.patch_path {
|
||||
Some(path) => Some(
|
||||
File::open(path)
|
||||
.with_context(|| format!("Could not open patch file at {:?}", path))?,
|
||||
.with_context(|| format!("Could not open patch file at {}", path.display()))?,
|
||||
),
|
||||
None => None,
|
||||
};
|
||||
|
|
@ -89,49 +87,42 @@ pub enum CacheFreshness {
|
|||
}
|
||||
|
||||
impl Cache {
|
||||
pub fn new<S>(url: S, platform: PlatformType) -> Self
|
||||
pub fn new<S, P>(url: S, platform: PlatformType, cache_dir: P) -> Result<Self>
|
||||
where
|
||||
S: Into<String>,
|
||||
P: Into<PathBuf>,
|
||||
{
|
||||
Self {
|
||||
// Check whether `cache_dir` exists and is a directory
|
||||
let cache_dir = cache_dir.into();
|
||||
let (cache_dir_exists, cache_dir_is_dir) = cache_dir
|
||||
.metadata()
|
||||
.map_or((false, false), |md| (true, md.is_dir()));
|
||||
ensure!(
|
||||
!cache_dir_exists || cache_dir_is_dir,
|
||||
"Cache directory path `{}` is not a directory",
|
||||
cache_dir.display(),
|
||||
);
|
||||
|
||||
// If necessary, create cache directory
|
||||
if !cache_dir_exists {
|
||||
// Try to create the complete directory path
|
||||
fs::create_dir_all(&cache_dir).with_context(|| {
|
||||
format!(
|
||||
"Cache directory path `{}` cannot be created",
|
||||
cache_dir.display(),
|
||||
)
|
||||
})?;
|
||||
eprintln!(
|
||||
"Successfully created cache directory path `{}`.",
|
||||
cache_dir.display(),
|
||||
);
|
||||
}
|
||||
|
||||
Ok(Self {
|
||||
url: url.into(),
|
||||
platform,
|
||||
}
|
||||
}
|
||||
|
||||
/// Return the path to the cache directory.
|
||||
pub fn get_cache_dir() -> Result<(PathBuf, PathSource)> {
|
||||
// Allow overriding the cache directory by setting the env variable.
|
||||
if let Ok(value) = env::var(CACHE_DIR_ENV_VAR) {
|
||||
let path = PathBuf::from(value);
|
||||
let (path_exists, path_is_dir) = path
|
||||
.metadata()
|
||||
.map_or((false, false), |md| (true, md.is_dir()));
|
||||
ensure!(
|
||||
!path_exists || path_is_dir,
|
||||
"Path specified by ${} is not a directory",
|
||||
CACHE_DIR_ENV_VAR
|
||||
);
|
||||
if !path_exists {
|
||||
// Try to create the complete directory path.
|
||||
fs::create_dir_all(&path).with_context(|| {
|
||||
format!(
|
||||
"Directory path specified by ${} cannot be created",
|
||||
CACHE_DIR_ENV_VAR
|
||||
)
|
||||
})?;
|
||||
eprintln!(
|
||||
"Successfully created cache directory path `{}`.",
|
||||
path.to_str().unwrap()
|
||||
);
|
||||
}
|
||||
return Ok((path, PathSource::EnvVar));
|
||||
};
|
||||
|
||||
// Otherwise, fall back to user cache directory.
|
||||
let dirs = get_app_root(AppDataType::UserCache, &crate::APP_INFO)
|
||||
.context("Could not determine user cache directory")?;
|
||||
Ok((dirs, PathSource::OsConvention))
|
||||
cache_dir,
|
||||
})
|
||||
}
|
||||
|
||||
/// Download the archive
|
||||
|
|
@ -171,12 +162,7 @@ impl Cache {
|
|||
.context("Could not decompress downloaded ZIP archive")?;
|
||||
|
||||
// Determine paths
|
||||
let (cache_dir, _) = Self::get_cache_dir()?;
|
||||
let pages_dir = cache_dir.join(TLDR_PAGES_DIR);
|
||||
|
||||
// Make sure that cache directory exists
|
||||
debug!("Ensure cache directory {:?} exists", &cache_dir);
|
||||
fs::create_dir_all(&cache_dir).context("Could not create cache directory")?;
|
||||
let pages_dir = self.cache_dir.join(TLDR_PAGES_DIR);
|
||||
|
||||
// Clear cache directory
|
||||
// Note: This is not the best solution. Ideally we would download the
|
||||
|
|
@ -184,7 +170,8 @@ impl Cache {
|
|||
// But renaming a directory doesn't work across filesystems and Rust
|
||||
// does not yet offer a recursive directory copying function. So for
|
||||
// now, we'll use this approach.
|
||||
Self::clear().context("Could not clear the cache directory")?;
|
||||
self.clear()
|
||||
.context("Could not clear the cache directory")?;
|
||||
|
||||
// Extract archive
|
||||
archive
|
||||
|
|
@ -195,21 +182,19 @@ 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(metadata) = fs::metadata(cache_dir.join(TLDR_PAGES_DIR)) {
|
||||
if let Ok(mtime) = metadata.modified() {
|
||||
let now = SystemTime::now();
|
||||
return now.duration_since(mtime).ok();
|
||||
};
|
||||
pub fn last_update(&self) -> Option<Duration> {
|
||||
if let Ok(metadata) = fs::metadata(self.cache_dir.join(TLDR_PAGES_DIR)) {
|
||||
if let Ok(mtime) = metadata.modified() {
|
||||
let now = SystemTime::now();
|
||||
return now.duration_since(mtime).ok();
|
||||
};
|
||||
};
|
||||
None
|
||||
}
|
||||
|
||||
/// Return the freshness of the cache (fresh, stale or missing).
|
||||
pub fn freshness() -> CacheFreshness {
|
||||
match Cache::last_update() {
|
||||
pub fn freshness(&self) -> CacheFreshness {
|
||||
match self.last_update() {
|
||||
Some(ago) if ago > crate::config::MAX_CACHE_AGE => CacheFreshness::Stale(ago),
|
||||
Some(_) => CacheFreshness::Fresh,
|
||||
None => CacheFreshness::Missing,
|
||||
|
|
@ -258,15 +243,8 @@ impl Cache {
|
|||
let patch_filename = format!("{}.patch", name);
|
||||
let custom_filename = format!("{}.page", name);
|
||||
|
||||
// Get cache dir
|
||||
let cache_dir = match Self::get_cache_dir() {
|
||||
Ok((cache_dir, _)) => cache_dir.join(TLDR_PAGES_DIR),
|
||||
Err(e) => {
|
||||
log::error!("Could not get cache directory: {}", e);
|
||||
return None;
|
||||
}
|
||||
};
|
||||
|
||||
// Determine directories
|
||||
let cache_dir = self.cache_dir.join(TLDR_PAGES_DIR);
|
||||
let lang_dirs: Vec<String> = languages
|
||||
.iter()
|
||||
.map(|lang| {
|
||||
|
|
@ -302,10 +280,9 @@ impl Cache {
|
|||
}
|
||||
|
||||
/// Return the available pages.
|
||||
pub fn list_pages(&self, custom_pages_dir: Option<&Path>) -> Result<Vec<String>> {
|
||||
pub fn list_pages(&self, custom_pages_dir: Option<&Path>) -> Vec<String> {
|
||||
// Determine platforms directory and platform
|
||||
let (cache_dir, _) = Self::get_cache_dir()?;
|
||||
let platforms_dir = cache_dir.join(TLDR_PAGES_DIR).join("pages");
|
||||
let platforms_dir = self.cache_dir.join(TLDR_PAGES_DIR).join("pages");
|
||||
let platform_dir = self.get_platform_dir();
|
||||
|
||||
// Closure that allows the WalkDir instance to traverse platform
|
||||
|
|
@ -367,29 +344,27 @@ impl Cache {
|
|||
|
||||
pages.sort();
|
||||
pages.dedup();
|
||||
Ok(pages)
|
||||
pages
|
||||
}
|
||||
|
||||
/// Delete the cache directory.
|
||||
pub fn clear() -> Result<()> {
|
||||
let (path, _) = Self::get_cache_dir()?;
|
||||
|
||||
pub fn clear(&self) -> Result<()> {
|
||||
// Check preconditions
|
||||
ensure!(
|
||||
path.exists(),
|
||||
self.cache_dir.exists(),
|
||||
"Cache path ({}) does not exist.",
|
||||
path.display(),
|
||||
self.cache_dir.display(),
|
||||
);
|
||||
ensure!(
|
||||
path.is_dir(),
|
||||
self.cache_dir.is_dir(),
|
||||
"Cache path ({}) is not a directory.",
|
||||
path.display()
|
||||
self.cache_dir.display(),
|
||||
);
|
||||
|
||||
// Delete old tldr-pages cache location as well if present
|
||||
// TODO: To be removed in the future
|
||||
for pages_dir_name in [TLDR_PAGES_DIR, TLDR_OLD_PAGES_DIR] {
|
||||
let pages_dir = path.join(pages_dir_name);
|
||||
let pages_dir = self.cache_dir.join(pages_dir_name);
|
||||
|
||||
if pages_dir.exists() {
|
||||
fs::remove_dir_all(&pages_dir).with_context(|| {
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ use std::{
|
|||
time::Duration,
|
||||
};
|
||||
|
||||
use anyhow::{ensure, Context, Result};
|
||||
use anyhow::{bail, ensure, Context, Result};
|
||||
use app_dirs::{get_app_root, AppDataType};
|
||||
use log::debug;
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
|
|
@ -164,6 +164,8 @@ impl Default for RawUpdatesConfig {
|
|||
|
||||
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||||
struct RawDirectoriesConfig {
|
||||
#[serde(default)]
|
||||
pub cache_dir: Option<PathBuf>,
|
||||
#[serde(default)]
|
||||
pub custom_pages_dir: Option<PathBuf>,
|
||||
}
|
||||
|
|
@ -171,6 +173,7 @@ struct RawDirectoriesConfig {
|
|||
impl Default for RawDirectoriesConfig {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
cache_dir: None,
|
||||
custom_pages_dir: get_app_root(AppDataType::UserData, &crate::APP_INFO)
|
||||
.map(|path| {
|
||||
// Note: The `join("")` call ensures that there's a trailing slash
|
||||
|
|
@ -239,6 +242,7 @@ pub struct UpdatesConfig {
|
|||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct DirectoriesConfig {
|
||||
pub cache_dir: PathBuf,
|
||||
pub custom_pages_dir: Option<PathBuf>,
|
||||
}
|
||||
|
||||
|
|
@ -250,34 +254,66 @@ pub struct Config {
|
|||
pub directories: DirectoriesConfig,
|
||||
}
|
||||
|
||||
impl From<RawConfig> for Config {
|
||||
fn from(raw_config: RawConfig) -> Self {
|
||||
Self {
|
||||
style: StyleConfig {
|
||||
command_name: raw_config.style.command_name.into(),
|
||||
description: raw_config.style.description.into(),
|
||||
example_text: raw_config.style.example_text.into(),
|
||||
example_code: raw_config.style.example_code.into(),
|
||||
example_variable: raw_config.style.example_variable.into(),
|
||||
},
|
||||
display: DisplayConfig {
|
||||
compact: raw_config.display.compact,
|
||||
use_pager: raw_config.display.use_pager,
|
||||
},
|
||||
updates: UpdatesConfig {
|
||||
auto_update: raw_config.updates.auto_update,
|
||||
auto_update_interval: Duration::from_secs(
|
||||
raw_config.updates.auto_update_interval_hours * 3600,
|
||||
),
|
||||
},
|
||||
directories: DirectoriesConfig {
|
||||
custom_pages_dir: raw_config.directories.custom_pages_dir,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Config {
|
||||
/// Convert a `RawConfig` to a high-level `Config`.
|
||||
///
|
||||
/// For this, some values need to be converted to other types and some
|
||||
/// defaults need to be set (sometimes based on env variables).
|
||||
fn from_raw(raw_config: RawConfig) -> Result<Self> {
|
||||
// Style config
|
||||
let style = StyleConfig {
|
||||
command_name: raw_config.style.command_name.into(),
|
||||
description: raw_config.style.description.into(),
|
||||
example_text: raw_config.style.example_text.into(),
|
||||
example_code: raw_config.style.example_code.into(),
|
||||
example_variable: raw_config.style.example_variable.into(),
|
||||
};
|
||||
|
||||
// Display config
|
||||
let display = DisplayConfig {
|
||||
compact: raw_config.display.compact,
|
||||
use_pager: raw_config.display.use_pager,
|
||||
};
|
||||
|
||||
// Updates config
|
||||
let updates = UpdatesConfig {
|
||||
auto_update: raw_config.updates.auto_update,
|
||||
auto_update_interval: Duration::from_secs(
|
||||
raw_config.updates.auto_update_interval_hours * 3600,
|
||||
),
|
||||
};
|
||||
|
||||
// Directories config
|
||||
let cache_dir_env_var = "TEALDEER_CACHE_DIR";
|
||||
let cache_dir = if let Ok(env_var) = env::var(cache_dir_env_var) {
|
||||
// For backwards compatibility reasons, the cache directory can be
|
||||
// overridden using an env variable. This is deprecated and will be
|
||||
// phased out in the future.
|
||||
eprintln!("Warning: The ${} env variable is deprecated, use the `cache_dir` option in the config file instead.", cache_dir_env_var);
|
||||
PathBuf::from(env_var)
|
||||
} else if let Some(config_value) = raw_config.directories.cache_dir {
|
||||
// If the user explicitly configured a cache directory, use that.
|
||||
config_value
|
||||
} else if let Ok(default_dir) = get_app_root(AppDataType::UserCache, &crate::APP_INFO) {
|
||||
// Otherwise, fall back to the default user cache directory.
|
||||
default_dir
|
||||
} else {
|
||||
// If everything fails, give up
|
||||
bail!("Could not determine user cache directory");
|
||||
};
|
||||
let directories = DirectoriesConfig {
|
||||
cache_dir,
|
||||
custom_pages_dir: raw_config.directories.custom_pages_dir,
|
||||
};
|
||||
|
||||
Ok(Self {
|
||||
style,
|
||||
display,
|
||||
updates,
|
||||
directories,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn load(enable_styles: bool) -> Result<Self> {
|
||||
debug!("Loading config");
|
||||
|
||||
|
|
@ -301,7 +337,7 @@ impl Config {
|
|||
};
|
||||
|
||||
// Convert to config
|
||||
let mut config = Self::from(raw_config);
|
||||
let mut config = Self::from_raw(raw_config).context("Could not process raw config")?;
|
||||
|
||||
// Potentially override styles
|
||||
if !enable_styles {
|
||||
|
|
|
|||
71
src/main.rs
71
src/main.rs
|
|
@ -59,11 +59,13 @@ const ARCHIVE_URL: &str = "https://tldr.sh/assets/tldr.zip";
|
|||
|
||||
/// The cache should be updated if it was explicitly requested,
|
||||
/// or if an automatic update is due and allowed.
|
||||
fn should_update_cache(args: &Args, config: &Config) -> bool {
|
||||
fn should_update_cache(cache: &Cache, args: &Args, config: &Config) -> bool {
|
||||
args.update
|
||||
|| (!args.no_auto_update
|
||||
&& config.updates.auto_update
|
||||
&& Cache::last_update().map_or(true, |ago| ago >= config.updates.auto_update_interval))
|
||||
&& cache
|
||||
.last_update()
|
||||
.map_or(true, |ago| ago >= config.updates.auto_update_interval))
|
||||
}
|
||||
|
||||
#[derive(PartialEq)]
|
||||
|
|
@ -73,8 +75,8 @@ enum CheckCacheResult {
|
|||
}
|
||||
|
||||
/// Check the cache for freshness. If it's stale or missing, show a warning.
|
||||
fn check_cache(args: &Args, enable_styles: bool) -> CheckCacheResult {
|
||||
match Cache::freshness() {
|
||||
fn check_cache(cache: &Cache, args: &Args, enable_styles: bool) -> CheckCacheResult {
|
||||
match cache.freshness() {
|
||||
CacheFreshness::Fresh => CheckCacheResult::CacheFound,
|
||||
CacheFreshness::Stale(_) if args.quiet => CheckCacheResult::CacheFound,
|
||||
CacheFreshness::Stale(age) => {
|
||||
|
|
@ -109,8 +111,8 @@ fn check_cache(args: &Args, enable_styles: bool) -> CheckCacheResult {
|
|||
}
|
||||
|
||||
/// Clear the cache
|
||||
fn clear_cache(quietly: bool, enable_styles: bool) {
|
||||
Cache::clear().unwrap_or_else(|e| {
|
||||
fn clear_cache(cache: &Cache, quietly: bool, enable_styles: bool) {
|
||||
cache.clear().unwrap_or_else(|e| {
|
||||
print_error(enable_styles, &e.context("Could not clear cache"));
|
||||
process::exit(1);
|
||||
});
|
||||
|
|
@ -157,28 +159,15 @@ fn show_paths(config: &Config) {
|
|||
);
|
||||
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
|
||||
match path.to_str() {
|
||||
Some(path) => format!("{} ({})", path, source),
|
||||
None => "[Invalid]".to_string(),
|
||||
}
|
||||
},
|
||||
);
|
||||
let pages_dir = Cache::get_cache_dir().map_or_else(
|
||||
|e| format!("[Error: {}]", e),
|
||||
|(mut path, _)| {
|
||||
path.push(TLDR_PAGES_DIR);
|
||||
path.push(""); // Trailing path separator
|
||||
path.into_os_string()
|
||||
.into_string()
|
||||
.unwrap_or_else(|_| "[Invalid]".to_string())
|
||||
},
|
||||
|(path, _)| path.display().to_string(),
|
||||
);
|
||||
let cache_dir = config.directories.cache_dir.display();
|
||||
let pages_dir = {
|
||||
let mut path = config.directories.cache_dir.clone();
|
||||
path.push(TLDR_PAGES_DIR);
|
||||
path.push(""); // Trailing path separator
|
||||
path.display().to_string()
|
||||
};
|
||||
let custom_pages_dir = config.directories.custom_pages_dir.as_deref().map_or_else(
|
||||
|| "[None]".to_string(),
|
||||
|path| {
|
||||
|
|
@ -339,15 +328,19 @@ fn main() {
|
|||
}
|
||||
|
||||
// Initialize cache
|
||||
let cache = Cache::new(ARCHIVE_URL, platform);
|
||||
let cache =
|
||||
Cache::new(ARCHIVE_URL, platform, &config.directories.cache_dir).unwrap_or_else(|e| {
|
||||
print_error(enable_styles, &e.context("Could not initialize cache"));
|
||||
process::exit(1);
|
||||
});
|
||||
|
||||
// Clear cache, pass through
|
||||
if args.clear_cache {
|
||||
clear_cache(args.quiet, enable_styles);
|
||||
clear_cache(&cache, args.quiet, enable_styles);
|
||||
}
|
||||
|
||||
// Cache update, pass through
|
||||
let cache_updated = if should_update_cache(&args, &config) {
|
||||
let cache_updated = if should_update_cache(&cache, &args, &config) {
|
||||
update_cache(&cache, args.quiet, enable_styles);
|
||||
true
|
||||
} else {
|
||||
|
|
@ -357,23 +350,19 @@ fn main() {
|
|||
// Check cache presence and freshness
|
||||
if !cache_updated
|
||||
&& (args.list || !args.command.is_empty())
|
||||
&& check_cache(&args, enable_styles) == CheckCacheResult::CacheMissing
|
||||
&& check_cache(&cache, &args, enable_styles) == CheckCacheResult::CacheMissing
|
||||
{
|
||||
process::exit(1);
|
||||
}
|
||||
|
||||
// List cached commands and exit
|
||||
if args.list {
|
||||
// Get list of pages
|
||||
let pages = cache
|
||||
.list_pages(config.directories.custom_pages_dir.as_deref())
|
||||
.unwrap_or_else(|e| {
|
||||
print_error(enable_styles, &e.context("Could not get list of pages"));
|
||||
process::exit(1);
|
||||
});
|
||||
|
||||
// Print pages
|
||||
println!("{}", pages.join("\n"));
|
||||
println!(
|
||||
"{}",
|
||||
cache
|
||||
.list_pages(config.directories.custom_pages_dir.as_deref())
|
||||
.join("\n")
|
||||
);
|
||||
process::exit(0);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -263,9 +263,12 @@ fn test_cache_location_not_a_directory() {
|
|||
.assert()
|
||||
.failure()
|
||||
.stderr(contains(format!(
|
||||
"Path specified by ${} is not a directory",
|
||||
CACHE_DIR_ENV_VAR
|
||||
)));
|
||||
"Cache directory path `{}` is not a directory",
|
||||
internal_file.display(),
|
||||
)))
|
||||
.stderr(contains(
|
||||
"Warning: The $TEALDEER_CACHE_DIR env variable is deprecated",
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue