From 7b61eb1595110d4de205d223d464b04be8fc2d68 Mon Sep 17 00:00:00 2001 From: Mario Stief Date: Fri, 20 Mar 2026 08:47:06 +0100 Subject: [PATCH] feat: new `--discard` for `ya pkg` that discard local changes made to packages (#3781) Co-authored-by: sxyazi --- CHANGELOG.md | 2 ++ Cargo.lock | 39 ++++++++++++--------------------- Cargo.toml | 2 +- yazi-cli/src/args.rs | 16 +++++++++++--- yazi-cli/src/dds/shot.rs | 4 ++-- yazi-cli/src/main.rs | 6 ++--- yazi-cli/src/package/add.rs | 4 ++-- yazi-cli/src/package/delete.rs | 6 ++--- yazi-cli/src/package/deploy.rs | 4 ++-- yazi-cli/src/package/hash.rs | 2 +- yazi-cli/src/package/install.rs | 4 ++-- yazi-cli/src/package/package.rs | 18 +++++++-------- yazi-cli/src/package/upgrade.rs | 4 ++-- yazi-shared/src/data/data.rs | 2 +- 14 files changed, 57 insertions(+), 56 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8758cc44..5c97d706 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,6 +27,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/): - New `ind-app-title` DDS event to customize the app title ([#3684]) - New `ind-hidden` and `key-hidden` DDS events to change hidden status in Lua ([#3748]) - New `marker_symbol` option to specify the symbol used for marking files ([#3689]) +- New `--discard` for `ya pkg` that discard local changes made to packages ([#3781]) - New `fs.unique()` creates a unique file or directory ([#3677]) - New `download` DDS event fires when remote files are downloaded ([#3687]) - New `ind-which-activate` DDS event to change the which component behavior ([#3608]) @@ -1686,3 +1687,4 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/): [#3757]: https://github.com/sxyazi/yazi/pull/3757 [#3765]: https://github.com/sxyazi/yazi/pull/3765 [#3780]: https://github.com/sxyazi/yazi/pull/3780 +[#3781]: https://github.com/sxyazi/yazi/pull/3781 diff --git a/Cargo.lock b/Cargo.lock index b89e4e89..e5210dcf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1388,9 +1388,9 @@ checksum = "dea2df4cf52843e0452895c455a1a2cfbb842a1e7329671acf418fdc53ed4c59" [[package]] name = "euclid" -version = "0.22.13" +version = "0.22.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df61bf483e837f88d5c2291dcf55c67be7e676b3a51acc48db3a7b163b91ed63" +checksum = "f1a05365e3b1c6d1650318537c7460c6923f1abdd272ad6842baa2b509957a06" dependencies = [ "num-traits", ] @@ -1879,15 +1879,6 @@ dependencies = [ "digest 0.10.7", ] -[[package]] -name = "home" -version = "0.5.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc627f471c528ff0c4a49e1d5e60450c8f6461dd6d10ba9dcd3a61d3dff7728d" -dependencies = [ - "windows-sys 0.61.2", -] - [[package]] name = "hybrid-array" version = "0.4.8" @@ -2106,9 +2097,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.17" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2" +checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" [[package]] name = "jobserver" @@ -3697,9 +3688,9 @@ dependencies = [ [[package]] name = "russh" -version = "0.57.1" +version = "0.58.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afe62631a04a1f4d71a14b99505483b95ff97c503b67d876c042fce659186956" +checksum = "30f6ce4f5d5105b934cfb4b8b3028aab4d5dcdff863cb8dda9edd06d39b8c4e8" dependencies = [ "aes", "bitflags 2.11.0", @@ -3722,7 +3713,6 @@ dependencies = [ "getrandom 0.2.17", "hex-literal", "hmac", - "home", "inout", "internal-russh-forked-ssh-key", "libcrux-ml-kem", @@ -3750,7 +3740,7 @@ dependencies = [ "spki 0.7.3", "ssh-encoding", "subtle", - "thiserror 1.0.69", + "thiserror 2.0.18", "tokio", "typenum", "zeroize", @@ -3758,15 +3748,14 @@ dependencies = [ [[package]] name = "russh-cryptovec" -version = "0.52.0" +version = "0.58.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fb0ed583ff0f6b4aa44c7867dd7108df01b30571ee9423e250b4cc939f8c6cf" +checksum = "cc109749696a6853cf2c3fba3537635264f3519a78a9f43c6b08c91edc024384" dependencies = [ - "libc", "log", "nix", "ssh-encoding", - "winapi", + "windows-sys 0.59.0", ] [[package]] @@ -6239,18 +6228,18 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.8.42" +version = "0.8.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2578b716f8a7a858b7f02d5bd870c14bf4ddbbcf3a4c05414ba6503640505e3" +checksum = "efbb2a062be311f2ba113ce66f697a4dc589f85e78a4aea276200804cea0ed87" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.42" +version = "0.8.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e6cc098ea4d3bd6246687de65af3f920c430e236bee1e3bf2e441463f08a02f" +checksum = "0e8bc7269b54418e7aeeef514aa68f8690b8c0489a06b0136e5f57c4c5ccab89" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index a7206601..2d8073c9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -62,7 +62,7 @@ percent-encoding = "2.3.2" rand = { version = "0.9.2", default-features = false, features = [ "os_rng", "small_rng", "std" ] } ratatui = { version = "0.30.0", features = [ "serde", "unstable-rendered-line-info", "unstable-widget-ref" ] } regex = "1.12.3" -russh = { version = "0.57.1", default-features = false, features = [ "ring", "rsa" ] } +russh = { version = "0.58.0", default-features = false, features = [ "ring", "rsa" ] } scopeguard = "1.2.0" serde = { version = "1.0.228", features = [ "derive" ] } serde_json = "1.0.149" diff --git a/yazi-cli/src/args.rs b/yazi-cli/src/args.rs index 591acb65..17b75040 100644 --- a/yazi-cli/src/args.rs +++ b/yazi-cli/src/args.rs @@ -77,17 +77,27 @@ pub(super) enum CommandPkg { Delete { /// Packages to delete. #[arg(index = 1, num_args = 1..)] - ids: Vec, + ids: Vec, + /// Discard local changes made to packages while deleting. + #[arg(long)] + discard: bool, }, /// Install all packages. - Install, + Install { + /// Discard local changes made to packages while installing. + #[arg(long)] + discard: bool, + }, /// List all packages. List, /// Upgrade all packages. Upgrade { /// Packages to upgrade, upgrade all if unspecified. #[arg(index = 1, num_args = 0..)] - ids: Vec, + ids: Vec, + /// Discard local changes made to packages while upgrading. + #[arg(long)] + discard: bool, }, } diff --git a/yazi-cli/src/dds/shot.rs b/yazi-cli/src/dds/shot.rs index 77db3957..dcc81955 100644 --- a/yazi-cli/src/dds/shot.rs +++ b/yazi-cli/src/dds/shot.rs @@ -44,11 +44,11 @@ impl Dds { } pub(super) fn ensure_version(version: Option<&str>) -> Result<()> { - if version.as_deref() != Some(EmberHi::version()) { + if version != Some(EmberHi::version()) { bail!( "Incompatible version (Ya {}, Yazi {}). Restart all `ya` and `yazi` processes if you upgrade either one.", EmberHi::version(), - version.as_deref().unwrap_or("Unknown") + version.unwrap_or("Unknown") ); } Ok(()) diff --git a/yazi-cli/src/main.rs b/yazi-cli/src/main.rs index f43e9228..b971ab9f 100644 --- a/yazi-cli/src/main.rs +++ b/yazi-cli/src/main.rs @@ -78,10 +78,10 @@ async fn run() -> anyhow::Result<()> { let mut pkg = package::Package::load().await?; match cmd { CommandPkg::Add { ids } => pkg.add_many(&ids).await?, - CommandPkg::Delete { ids } => pkg.delete_many(&ids).await?, - CommandPkg::Install => pkg.install().await?, + CommandPkg::Delete { ids, discard } => pkg.delete_many(&ids, discard).await?, + CommandPkg::Install { discard } => pkg.install(discard).await?, CommandPkg::List => pkg.print()?, - CommandPkg::Upgrade { ids } => pkg.upgrade_many(&ids).await?, + CommandPkg::Upgrade { ids, discard } => pkg.upgrade_many(&ids, discard).await?, } } diff --git a/yazi-cli/src/package/add.rs b/yazi-cli/src/package/add.rs index b3d019e8..6ae7a42c 100644 --- a/yazi-cli/src/package/add.rs +++ b/yazi-cli/src/package/add.rs @@ -4,7 +4,7 @@ use super::{Dependency, Git}; use crate::shared::must_exists; impl Dependency { - pub(super) async fn add(&mut self) -> Result<()> { + pub(super) async fn add(&mut self, discard: bool) -> Result<()> { self.header("Upgrading package `{name}`")?; let path = self.local(); @@ -14,7 +14,7 @@ impl Dependency { Git::clone(&self.remote(), &path).await?; }; - self.deploy().await?; + self.deploy(discard).await?; self.rev = Git::revision(&path).await?; Ok(()) } diff --git a/yazi-cli/src/package/delete.rs b/yazi-cli/src/package/delete.rs index 4968e143..9f548c1f 100644 --- a/yazi-cli/src/package/delete.rs +++ b/yazi-cli/src/package/delete.rs @@ -6,18 +6,18 @@ use super::Dependency; use crate::shared::{maybe_exists, remove_sealed}; impl Dependency { - pub(super) async fn delete(&self) -> Result<()> { + pub(super) async fn delete(&self, discard: bool) -> Result<()> { self.header("Deleting package `{name}`")?; let dir = self.target(); if !maybe_exists(&dir).await { return Ok(outln!("Not found, skipping")?); + } else if !discard { + self.hash_check().await?; } - self.hash_check().await?; self.delete_assets().await?; self.delete_sources().await?; - Ok(()) } diff --git a/yazi-cli/src/package/deploy.rs b/yazi-cli/src/package/deploy.rs index 2cc10ac5..ffbe5f5e 100644 --- a/yazi-cli/src/package/deploy.rs +++ b/yazi-cli/src/package/deploy.rs @@ -8,7 +8,7 @@ use super::Dependency; use crate::shared::{copy_and_seal, maybe_exists}; impl Dependency { - pub(super) async fn deploy(&mut self) -> Result<()> { + pub(super) async fn deploy(&mut self, discard: bool) -> Result<()> { let from = self.local().join(&self.child); self.header("Deploying package `{name}`")?; @@ -16,7 +16,7 @@ impl Dependency { let to = self.target(); let exists = maybe_exists(&to).await; - if exists { + if exists && !discard { self.hash_check().await?; } diff --git a/yazi-cli/src/package/hash.rs b/yazi-cli/src/package/hash.rs index 37fc5350..39a4e62b 100644 --- a/yazi-cli/src/package/hash.rs +++ b/yazi-cli/src/package/hash.rs @@ -46,7 +46,7 @@ impl Dependency { if self.hash != self.hash().await? { bail!( "You have modified the contents of the `{}` {}. For safety, the operation has been aborted. -Please manually delete it from `{}` and re-run the command.", +Please manually delete it from `{}` and re-run the command, or use `--discard` to discard those local changes.", self.name, if self.is_flavor { "flavor" } else { "plugin" }, self.target().display() diff --git a/yazi-cli/src/package/install.rs b/yazi-cli/src/package/install.rs index 9c48e004..4ebda2da 100644 --- a/yazi-cli/src/package/install.rs +++ b/yazi-cli/src/package/install.rs @@ -4,7 +4,7 @@ use super::{Dependency, Git}; use crate::shared::must_exists; impl Dependency { - pub(super) async fn install(&mut self) -> Result<()> { + pub(super) async fn install(&mut self, discard: bool) -> Result<()> { self.header("Fetching package `{name}`")?; let path = self.local(); @@ -18,7 +18,7 @@ impl Dependency { Git::checkout(&path, self.rev.trim_start_matches('=')).await?; } - self.deploy().await?; + self.deploy(discard).await?; if self.rev.is_empty() { self.rev = Git::revision(&path).await?; } diff --git a/yazi-cli/src/package/package.rs b/yazi-cli/src/package/package.rs index dc654bc7..40deb14b 100644 --- a/yazi-cli/src/package/package.rs +++ b/yazi-cli/src/package/package.rs @@ -28,19 +28,19 @@ impl Package { Ok(()) } - pub(crate) async fn delete_many(&mut self, uses: &[String]) -> Result<()> { + pub(crate) async fn delete_many(&mut self, uses: &[String], discard: bool) -> Result<()> { for u in uses { - let r = self.delete(u).await; + let r = self.delete(u, discard).await; self.save().await?; r?; } Ok(()) } - pub(crate) async fn install(&mut self) -> Result<()> { + pub(crate) async fn install(&mut self, discard: bool) -> Result<()> { macro_rules! go { ($dep:expr) => { - let r = $dep.install().await; + let r = $dep.install(discard).await; self.save().await?; r?; }; @@ -55,11 +55,11 @@ impl Package { Ok(()) } - pub(crate) async fn upgrade_many(&mut self, uses: &[String]) -> Result<()> { + pub(crate) async fn upgrade_many(&mut self, uses: &[String], discard: bool) -> Result<()> { macro_rules! go { ($dep:expr) => { if uses.is_empty() || uses.contains(&$dep.r#use) { - let r = $dep.upgrade().await; + let r = $dep.upgrade(discard).await; self.save().await?; r?; } @@ -107,7 +107,7 @@ impl Package { ) } - dep.add().await?; + dep.add(false).await?; if dep.is_flavor { self.flavors.push(dep); } else { @@ -116,12 +116,12 @@ impl Package { Ok(()) } - async fn delete(&mut self, r#use: &str) -> Result<()> { + async fn delete(&mut self, r#use: &str, discard: bool) -> Result<()> { let Some(dep) = self.identical(&Dependency::from_str(r#use)?).cloned() else { bail!("`{}` was not found in package.toml", r#use) }; - dep.delete().await?; + dep.delete(discard).await?; if dep.is_flavor { self.flavors.retain(|d| !d.identical(&dep)); } else { diff --git a/yazi-cli/src/package/upgrade.rs b/yazi-cli/src/package/upgrade.rs index a9cb8539..304d8ba8 100644 --- a/yazi-cli/src/package/upgrade.rs +++ b/yazi-cli/src/package/upgrade.rs @@ -3,7 +3,7 @@ use anyhow::Result; use super::Dependency; impl Dependency { - pub(super) async fn upgrade(&mut self) -> Result<()> { - if self.rev.starts_with('=') { Ok(()) } else { self.add().await } + pub(super) async fn upgrade(&mut self, discard: bool) -> Result<()> { + if self.rev.starts_with('=') { Ok(()) } else { self.add(discard).await } } } diff --git a/yazi-shared/src/data/data.rs b/yazi-shared/src/data/data.rs index a0146b27..6db6fb84 100644 --- a/yazi-shared/src/data/data.rs +++ b/yazi-shared/src/data/data.rs @@ -219,7 +219,7 @@ impl Data { pub fn as_any(&self) -> Option<&T> { match self { - Self::Any(b) => (&**b).as_any().downcast_ref::(), + Self::Any(b) => (**b).as_any().downcast_ref::(), _ => None, } }