delete uncorrect

This commit is contained in:
pivodevat
2025-06-02 18:00:32 +03:00
parent 5918b2c4b2
commit 51ffa435fb
16 changed files with 666 additions and 76 deletions

117
src/commands/delete.rs Normal file
View File

@ -0,0 +1,117 @@
use std::fs;
use std::io;
use std::path::Path;
use rayon::prelude::*;
use std::os::unix::fs::MetadataExt;
use super::get_var_path;
use crate::utils::parser;
pub fn delete(repo: &str, pkgname: &str) {
let base_dir = Path::new("/pkg").join(repo);
let pkg_dir = base_dir.join(pkgname);
if pkg_dir.exists() {
match fs::remove_dir_all(&pkg_dir) {
Ok(()) => { println!("removed: {}", pkg_dir.display()) }
Err(e) => { eprintln!("Can't remove {}: {}", pkg_dir.display(), e)}
}
} else {
eprintln!("{} not installed in {}", pkgname, repo)
}
let subdirs = ["lib", "include", "bin"];
for subdir in &subdirs {
let dir_path = base_dir.join(subdir);
if dir_path.exists() {
match remove_unused_files(&dir_path) {
Ok(()) => {}
Err(_) => {}
}
}
}
}
pub fn delete_recursive(repo: &str, pkgname: &str) {
let base_dir = Path::new("/pkg").join(repo);
let pkg_dir = base_dir.join(pkgname);
if pkg_dir.exists() {
let var_path = get_var_path();
let pkg_md_path = var_path.join(format!("{}/{}.md", repo, pkgname));
match parser::get_deps(&pkg_md_path) {
Ok(deps) => {
for dependency in deps.lines() {
let dependency = dependency.trim();
if !dependency.is_empty() {
let pkg_dir = Path::new("/pkg").join(repo).join(dependency);
if pkg_dir.exists() {
if !parser::get_use_status(repo, dependency) {
delete(repo, &dependency.to_string())
}
}
}
}
}
Err(e) => {
eprintln!("Failed to parse dependencies: {}", e)
}
}
match fs::remove_dir_all(&pkg_dir) {
Ok(()) => { println!("removed: {}", pkg_dir.display()) }
Err(e) => { eprintln!("Can't remove {}: {}", pkg_dir.display(), e)}
}
} else {
eprintln!("{} not installed in {}", pkgname, repo)
}
let subdirs = ["lib", "include", "bin"];
for subdir in &subdirs {
let dir_path = base_dir.join(subdir);
if dir_path.exists() {
match remove_unused_files(&dir_path) {
Ok(()) => {}
Err(_) => {}
}
}
}
}
fn remove_unused_files(dir: &Path) -> Result<(), String> {
let entries = fs::read_dir(dir)
.map_err(|e| format!("Can't read {}: {}", dir.display(), e))?;
entries.par_bridge().for_each(|entry| {
if let Ok(entry) = entry {
let path = entry.path();
if path.is_file() {
if let Ok(nlink) = get_nlink(&path) {
if nlink == 1 {
if let Err(e) = fs::remove_file(&path) {
eprintln!("Can't remove {}: {}", path.display(), e)
}
}
}
} else if path.is_dir() {
if let Err(e) = remove_unused_files(&path) { eprintln!("Error processing directory {}: {}", path.display(), e) }
} else if path.is_symlink() {
if fs::read_link(&path).is_err() {
if let Err(e) = fs::remove_file(&path) { eprintln!("Can't remove symlink {}: {}", path.display(), e) }
}
}
}
});
Ok(())
}
fn get_nlink(path: &Path) -> io::Result<u64> {
Ok(fs::metadata(path)?.nlink())
}