feat: added clear-cache argument

This commit is contained in:
Byson94
2025-08-16 17:48:20 +05:30
parent 60cf726a93
commit d9fdb6d246
8 changed files with 139 additions and 18 deletions

View File

@@ -6,4 +6,5 @@
- [Uninstall](./uninstall_command.md)
- [Update](./update_command.md)
- [List](./list_command.md)
- [Clear Cache](./clear_cache.md)
- [Examples](./examples.md)

27
docs/src/clear_cache.md Normal file
View File

@@ -0,0 +1,27 @@
# Clear Cache
### Command
Clear package cache
```bash
eiipm clear-cache [PACKAGE]
# or shorter:
eiipm cc [PACKAGE]
```
### Description
- If PACKAGE is given, then it clears the cache of that package.
- If no package is given, then it clears cache of all installed packages.
### Options
**--debug**: Show debug logs.
### Examples
```bash
eiipm cc # clear all
eiipm clear-cache statictranspl # clear just one package cache
```

View File

@@ -0,0 +1,58 @@
use super::{InstalledPackage, save_db, load_db};
use log::{info, debug};
use std::error::Error;
use std::path::PathBuf;
use std::fs;
use colored::Colorize;
pub fn clean_package_cache(package_name: Option<String>) -> Result<(), Box<dyn Error>> {
let mut db = load_db()?;
if let Some(name) = package_name {
if let Some(pkg) = db.packages.get_mut(&name) {
info!("> Clearing '{}' cache", name.yellow().bold());
clear_file_cache(pkg, &name)?;
} else {
info!("Package '{}' not found in database", name.yellow());
}
} else {
info!("> Clearing all package cache...");
for (name, pkg) in db.packages.iter_mut() {
info!("Clearing '{}' cache", name.yellow().bold());
clear_file_cache(pkg, name)?;
}
}
save_db(&db)?;
Ok(())
}
fn clear_file_cache(pkg: &mut InstalledPackage, package_name: &str) -> Result<(), Box<dyn Error>> {
let repo_path = PathBuf::from(&pkg.repo_path);
let home_dir = dirs::home_dir().ok_or("Failed to get home directory")?;
let cache_root = home_dir.join(".eiipm/cache");
if !repo_path.exists() {
info!("Cache of package '{}' doesn't exist. Skipping...", package_name);
return Ok(());
} else {
debug!("Running catastrophe preventer code before removing cache.");
if !repo_path.starts_with(cache_root.as_path()) {
return Err(format!("Refusing to delete outside cache: {}", repo_path.display()).into());
}
match fs::remove_dir_all(repo_path) {
Ok(_) => info!("Successfully cleared '{}' cache", package_name.yellow().bold()),
Err(e) => {
return Err(format!(
"Error removing cache of '{}'. Caused by: {}",
package_name,
e
).into());
},
}
}
Ok(())
}

View File

@@ -54,7 +54,7 @@ pub fn install_package(package_name: &str) -> Result<(), Box<dyn Error>> {
if !repo_path.exists() {
info!("Cloning repository {} to {}", meta.src.underline(), repo_path.display());
let output = Command::new("git")
.args(&["clone", &meta.src, repo_path.to_str().unwrap()])
.args(&["clone", "--depth=1", &meta.src, repo_path.to_str().unwrap()])
.output()?;
if !output.status.success() {
return Err(format!("Git clone failed: {}", String::from_utf8_lossy(&output.stderr)).into());
@@ -120,6 +120,7 @@ pub fn install_package(package_name: &str) -> Result<(), Box<dyn Error>> {
installed_files: installed_files,
copy_files: meta.files.clone(),
pkg_type: meta.pkg_type.clone(),
upstream_src: meta.src.clone(),
build_command: meta.build.clone(),
},
);

View File

@@ -2,6 +2,7 @@ pub mod install;
pub mod uninstall;
pub mod update;
pub mod list;
pub mod clearcache;
use std::fs;
use std::error::Error;
@@ -16,12 +17,19 @@ pub struct PackageDB {
packages: HashMap<String, InstalledPackage>,
}
// Wait there dev!
// if you add a new value to InstalledPackage, eiipm will break
// no... no... eiipm wont break, but old db's that use the old
// struct will break... So, remember to add `#[serde(default)]`.
// #[serde(default)] is our lord and savior if we need to add a new value.
#[derive(Deserialize, Serialize, Debug)]
pub struct InstalledPackage {
repo_path: String,
repo_path: String, // path to cached repo. E.g. ~/.eiipm/cache/<REPO_NAME>
installed_files: Vec<String>,
copy_files: Vec<String>,
pkg_type: String,
upstream_src: String,
build_command: Option<String>,
}

View File

@@ -7,11 +7,11 @@ use std::env;
use std::process::Command;
use colored::Colorize;
pub fn update_package(package_name: Option<String>) -> Result<(), Box<dyn Error>> {
pub fn update_package(package_name: &Option<String>) -> Result<(), Box<dyn Error>> {
let mut db = load_db()?;
if let Some(name) = package_name {
if let Some(pkg) = db.packages.get_mut(&name) {
if let Some(pkg) = db.packages.get_mut(name) {
info!("> Updating package '{}'", name.yellow().bold());
update_file(pkg, &name)?;
info!("Successfully updated '{}'", name.yellow().bold());
@@ -33,16 +33,24 @@ pub fn update_package(package_name: Option<String>) -> Result<(), Box<dyn Error>
fn update_file(pkg: &mut InstalledPackage, package_name: &str) -> Result<(), Box<dyn Error>> {
let repo_path = PathBuf::from(&pkg.repo_path);
// Pull latest changes
// Clone/Pull latest changes
debug!("Pullng latest version of {} using git...", package_name);
let output = Command::new("git")
.args(&["-C", repo_path.to_str().unwrap(), "pull"])
.output()?;
if !output.status.success() {
return Err(format!(
"Git pull failed: {}",
String::from_utf8_lossy(&output.stderr)
).into());
if !repo_path.exists() {
info!("Cache not found. Cloning repository {} to {}", pkg.upstream_src.underline(), repo_path.display());
let output = Command::new("git")
.args(&["clone", "--depth=1", &pkg.upstream_src, repo_path.to_str().unwrap()])
.output()?;
if !output.status.success() {
return Err(format!("Git clone failed: {}", String::from_utf8_lossy(&output.stderr)).into());
}
} else {
info!("Repository is cached, pulling latest changes");
let output = Command::new("git")
.args(&["-C", repo_path.to_str().unwrap(), "pull"])
.output()?;
if !output.status.success() {
return Err(format!("Git pull failed: {}", String::from_utf8_lossy(&output.stderr)).into());
}
}
// Optional build step

View File

@@ -6,7 +6,8 @@ use functions::{
install::install_package,
uninstall::uninstall_package,
update::update_package,
list::list_packages
list::list_packages,
clearcache::clean_package_cache,
};
use clap::Parser;
@@ -33,10 +34,17 @@ fn main() {
}
}
Commands::Update { package } => {
if Some(&package).is_some() {
let _ = update_package(package);
} else {
let _ = update_package(None);
match &package {
Some(name) => {
if let Err(e) = update_package(&Some(name.clone())) {
error!("Error updating '{}'. Caused by: {}", name, e);
}
}
None => {
if let Err(e) = update_package(&None) {
error!("Error updating all packages: {}", e);
}
}
}
}
Commands::List(list_args) => {
@@ -44,6 +52,11 @@ fn main() {
error!("Error listing packages: {}", e);
}
}
Commands::ClearCache { package } => {
if let Err(e) = clean_package_cache(package) {
error!("Error clearing package cache: {}", e);
}
}
}
}

View File

@@ -36,6 +36,11 @@ pub enum Commands {
/// List all installed packages
#[command(alias = "l")]
List(ListArgs),
/// Clean a package or all package cache
#[command(alias = "cc")]
ClearCache {
package: Option<String>,
},
}
#[derive(Args, Debug)]