From ddc9465ec823b790c0ba0028a1d2884440ba87ca Mon Sep 17 00:00:00 2001 From: Danny Moesch Date: Sat, 10 Apr 2021 18:24:33 +0200 Subject: [PATCH] Create cache directory path if it does not exist --- src/cache.rs | 33 ++++++++++++++++++++++++--------- tests/lib.rs | 51 +++++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 71 insertions(+), 13 deletions(-) diff --git a/src/cache.rs b/src/cache.rs index 409e228c..4c807dc1 100644 --- a/src/cache.rs +++ b/src/cache.rs @@ -15,6 +15,8 @@ use walkdir::{DirEntry, WalkDir}; use crate::error::TealdeerError::{self, CacheError, UpdateError}; use crate::types::{OsType, PathSource}; +static CACHE_DIR: &str = "TEALDEER_CACHE_DIR"; + #[derive(Debug)] pub struct Cache { url: String, @@ -36,18 +38,31 @@ impl Cache { 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") { + if let Ok(value) = env::var(CACHE_DIR) { let path = PathBuf::from(value); - if path.exists() && path.is_dir() { - return Ok((path, PathSource::EnvVar)); - } else { - return Err(CacheError( - "Path specified by $TEALDEER_CACHE_DIR \ - does not exist or is not a directory." - .into(), - )); + if path.exists() { + if path.is_dir() { + return Ok((path, PathSource::EnvVar)); + } + return Err(CacheError(format!( + "Path specified by ${} is not a directory.", + CACHE_DIR + ))); } + + // Try to create the complete directory path. + fs::create_dir_all(&path).map_err(|_| { + CacheError(format!( + "Directory path specified by ${} cannot be created.", + CACHE_DIR + )) + })?; + println!( + "Successfully created cache directory path `{}`.", + path.to_str().unwrap() + ); + return Ok((path, PathSource::EnvVar)); }; // Otherwise, fall back to user cache directory. diff --git a/tests/lib.rs b/tests/lib.rs index 7f7ad4ca..5a6e8d6d 100644 --- a/tests/lib.rs +++ b/tests/lib.rs @@ -16,6 +16,8 @@ use predicates::boolean::PredicateBooleanExt; use predicates::prelude::predicate::str::{contains, is_empty, similar}; use tempfile::{Builder, TempDir}; +static CACHE_DIR: &str = "TEALDEER_CACHE_DIR"; + struct TestEnv { pub cache_dir: TempDir, pub config_dir: TempDir, @@ -77,10 +79,7 @@ impl TestEnv { } let run = build.run().unwrap(); let mut cmd = run.command(); - cmd.env( - "TEALDEER_CACHE_DIR", - self.cache_dir.path().to_str().unwrap(), - ); + cmd.env(CACHE_DIR, self.cache_dir.path().to_str().unwrap()); cmd.env( "TEALDEER_CONFIG_DIR", self.config_dir.path().to_str().unwrap(), @@ -189,6 +188,50 @@ fn test_quiet_old_cache() { .stderr(contains("The cache hasn't been updated for more than ").not()); } +#[test] +fn test_create_cache_directory_path() { + let testenv = TestEnv::new(); + let cache_dir = testenv.cache_dir.path(); + let internal_cache_dir = cache_dir.join("internal"); + + let mut command = testenv.command(); + command.env(CACHE_DIR, internal_cache_dir.to_str().unwrap()); + + assert!(!internal_cache_dir.exists()); + + command + .arg("-u") + .assert() + .success() + .stdout(contains(format!( + "Successfully created cache directory path `{}`.", + internal_cache_dir.to_str().unwrap() + ))) + .stdout(contains("Successfully updated cache.")); + + assert!(internal_cache_dir.exists()); +} + +#[test] +fn test_cache_location_not_a_directory() { + let testenv = TestEnv::new(); + let cache_dir = testenv.cache_dir.path(); + let internal_file = cache_dir.join("internal"); + File::create(&internal_file).unwrap(); + + let mut command = testenv.command(); + command.env(CACHE_DIR, internal_file.to_str().unwrap()); + + command + .arg("-u") + .assert() + .failure() + .stderr(contains(format!( + "Path specified by ${} is not a directory.", + CACHE_DIR + ))); +} + #[test] fn test_setup_seed_config() { let testenv = TestEnv::new();