From 0520ae8fc6e7e560e343a4dffa4c7b514adf92c3 Mon Sep 17 00:00:00 2001 From: Chawye Hsu Date: Wed, 26 Jul 2023 11:05:16 +0800 Subject: [PATCH] fix(libscoop): ensure ops working dir exist Signed-off-by: Chawye Hsu --- crates/libscoop/src/config.rs | 7 +++- crates/libscoop/src/internal/fs.rs | 9 ++++- crates/libscoop/src/operation.rs | 60 ++++++++++++++++++---------- crates/libscoop/src/package/query.rs | 4 +- 4 files changed, 56 insertions(+), 24 deletions(-) diff --git a/crates/libscoop/src/config.rs b/crates/libscoop/src/config.rs index ee8e5ee..606bc6c 100644 --- a/crates/libscoop/src/config.rs +++ b/crates/libscoop/src/config.rs @@ -98,7 +98,7 @@ pub struct ConfigInner { #[serde(alias = "cachePath")] #[serde(default = "default::cache_path")] #[serde(skip_serializing_if = "default::is_default_cache_path")] - pub cache_path: PathBuf, + cache_path: PathBuf, #[serde(skip_serializing_if = "Option::is_none")] cat_style: Option, @@ -174,6 +174,11 @@ impl Config { config } + #[inline] + pub fn cache_path(&self) -> &Path { + self.cache_path.as_path() + } + #[inline] pub fn root_path(&self) -> &Path { self.root_path.as_path() diff --git a/crates/libscoop/src/internal/fs.rs b/crates/libscoop/src/internal/fs.rs index 8301004..788e080 100644 --- a/crates/libscoop/src/internal/fs.rs +++ b/crates/libscoop/src/internal/fs.rs @@ -21,10 +21,15 @@ pub fn remove_dir + ?Sized>(path: &P) -> io::Result<()> { remove_dir_all::remove_dir_all(path.as_ref()) } +/// Remove all files and subdirectories in given `path`. +/// +/// This function will not remove the given `path` itself. No-op if the given +/// `path` does not exist. #[inline(always)] pub fn empty_dir + ?Sized>(path: &P) -> io::Result<()> { - match path.as_ref().exists() { - true => remove_dir_all::remove_dir_contents(path.as_ref()), + let path = path.as_ref(); + match path.exists() { + true => remove_dir_all::remove_dir_contents(path), false => Ok(()), } } diff --git a/crates/libscoop/src/operation.rs b/crates/libscoop/src/operation.rs index af9e3c3..7685f05 100644 --- a/crates/libscoop/src/operation.rs +++ b/crates/libscoop/src/operation.rs @@ -50,11 +50,12 @@ use crate::{ /// A git error will be returned if failed to clone the bucket. pub fn bucket_add(session: &Session, name: &str, remote_url: &str) -> Fallible<()> { let config = session.config(); - let mut path = config.root_path.clone(); - + let mut path = config.root_path().to_owned(); path.push("buckets"); - path.push(name); + internal::fs::ensure_dir(&path)?; + + path.push(name); if path.exists() { return Err(Error::BucketAlreadyExists(name.to_owned())); } @@ -201,7 +202,7 @@ pub fn bucket_update(session: &Session) -> Fallible<()> { /// This method will return an error if the bucket does not exist. I/O errors /// will be returned if the bucket directory is unable to be removed. pub fn bucket_remove(session: &Session, name: &str) -> Fallible<()> { - let mut path = session.config().root_path.clone(); + let mut path = session.config().root_path().to_owned(); path.push("buckets"); path.push(name); @@ -222,24 +223,39 @@ pub fn bucket_remove(session: &Session, name: &str) -> Fallible<()> { /// /// I/O errors will be returned if the cache directory is not readable. pub fn cache_list(session: &Session, query: &str) -> Fallible> { - let mut entires = session - .config() - .cache_path + let is_wildcard_query = query.eq("*") || query.is_empty(); + let config = session.config(); + let cache_dir = config.cache_path(); + + internal::fs::ensure_dir(&cache_dir)?; + + let entries = cache_dir .read_dir()? .filter_map(Result::ok) - .filter(|e| e.file_type().unwrap().is_file()) - .filter_map(|de| CacheFile::from(de.path()).ok()) + .filter_map(|de| { + let is_file = de.file_type().unwrap().is_file(); + if is_file { + if let Ok(item) = CacheFile::from(de.path()) { + if !is_wildcard_query { + let matched = item + .package_name() + .to_lowercase() + .contains(&query.to_lowercase()); + if matched { + return Some(item); + } else { + return None; + } + } + + return Some(item); + } + } + None + }) .collect::>(); - match query { - "" | "*" => {} - query => { - entires = entires - .into_iter() - .filter(|f| f.package_name().contains(query)) - .collect::>(); - } - } - Ok(entires) + + Ok(entries) } /// Remove cache files by query. @@ -250,7 +266,11 @@ pub fn cache_list(session: &Session, query: &str) -> Fallible> { /// to remove the cache files. pub fn cache_remove(session: &Session, query: &str) -> Fallible<()> { match query { - "*" => Ok(fs::empty_dir(&session.config().cache_path)?), + "*" => { + let config = session.config(); + let cache_dir = config.cache_path(); + Ok(internal::fs::empty_dir(cache_dir)?) + } query => { let files = cache_list(session, query)?; for f in files.into_iter() { diff --git a/crates/libscoop/src/package/query.rs b/crates/libscoop/src/package/query.rs index 1085e68..3563008 100644 --- a/crates/libscoop/src/package/query.rs +++ b/crates/libscoop/src/package/query.rs @@ -5,7 +5,7 @@ use regex::{Regex, RegexBuilder}; use crate::{ bucket::Bucket, error::Fallible, - internal::compare_versions, + internal::{self, compare_versions}, package::manifest::{InstallInfo, Manifest}, Session, }; @@ -97,6 +97,8 @@ pub(crate) fn query_installed( } } + internal::fs::ensure_dir(&apps_dir)?; + let packages = apps_dir .read_dir()? .par_bridge()