yazi/yazi-cli/src/package/delete.rs
2025-07-27 18:06:13 +08:00

67 lines
1.8 KiB
Rust

use anyhow::{Context, Result};
use yazi_fs::{ok_or_not_found, remove_dir_clean, services::Local};
use yazi_macro::outln;
use yazi_shared::url::Url;
use super::Dependency;
use crate::shared::{maybe_exists, remove_sealed};
impl Dependency {
pub(super) async fn delete(&self) -> Result<()> {
self.header("Deleting package `{name}`")?;
let dir = self.target();
if !maybe_exists(&dir).await {
return Ok(outln!("Not found, skipping")?);
}
self.hash_check().await?;
self.delete_assets().await?;
self.delete_sources().await?;
Ok(())
}
pub(super) async fn delete_assets(&self) -> Result<()> {
let assets = self.target().join("assets");
match Local::read_dir(&assets).await {
Ok(mut it) => {
while let Some(entry) = it.next_entry().await? {
remove_sealed(&entry.path())
.await
.with_context(|| format!("failed to remove `{}`", entry.path().display()))?;
}
}
Err(e) if e.kind() == std::io::ErrorKind::NotFound => {}
Err(e) => Err(e).context(format!("failed to read `{}`", assets.display()))?,
};
remove_dir_clean(&assets.into()).await;
Ok(())
}
pub(super) async fn delete_sources(&self) -> Result<()> {
let dir = self.target();
let files = if self.is_flavor {
&["flavor.toml", "tmtheme.xml", "README.md", "preview.png", "LICENSE", "LICENSE-tmtheme"][..]
} else {
&["main.lua", "README.md", "LICENSE"][..]
};
for p in files.iter().map(|&f| dir.join(f)) {
ok_or_not_found(remove_sealed(&p).await)
.with_context(|| format!("failed to delete `{}`", p.display()))?;
}
if ok_or_not_found(Local::remove_dir(&dir).await).is_ok() {
outln!("Done!")?;
} else {
outln!(
"Done!
For safety, user data has been preserved, please manually delete them within: {}",
dir.display()
)?;
}
Ok(())
}
}