File 0001-packages-add-zypper-support-from-openSUSE.patch of Package i3status-rust

From 9ab615a220fa044be83c5fbebfe769c86a030a07 Mon Sep 17 00:00:00 2001
From: Clemens Famulla-Conrad <cfamullaconrad@suse.com>
Date: Fri, 13 Mar 2026 16:47:37 +0100
Subject: [PATCH] packages: add zypper support from openSUSE

---
 src/blocks/packages.rs        | 31 ++++++++++++++++++++++++++--
 src/blocks/packages/zypper.rs | 38 +++++++++++++++++++++++++++++++++++
 2 files changed, 67 insertions(+), 2 deletions(-)
 create mode 100644 src/blocks/packages/zypper.rs

diff --git a/src/blocks/packages.rs b/src/blocks/packages.rs
index 5f74e8f1a..91aafc07a 100644
--- a/src/blocks/packages.rs
+++ b/src/blocks/packages.rs
@@ -10,6 +10,7 @@
 //! - `pacman` for Arch-based systems
 //! - `snap` for Snap packages
 //! - `xbps` for Void Linux
+//! - `zypper` for openSUSE
 //!
 //! # Configuration
 //!
@@ -38,6 +39,7 @@
 //! `pacman`     | Number of updates available in Arch-based systems                                | Number | -
 //! `snap`       | Number of updates available in Snap packages                                     | Number | -
 //! `xbps`       | Number of updates available in Void Linux                                        | Number | -
+//! `zypper`     | Number of updates available in openSUSE                                          | Number | -
 //! `total`      | Number of updates available in all package manager listed                        | Number | -
 //!
 //! # Apt
@@ -252,6 +254,24 @@
 //! cmd = "xbps-install -Mun | dmenu -l 10"
 //! ```
 //!
+//! Zypper-only config:
+//!
+//! ```toml
+//! [[block]]
+//! block = "packages"
+//! package_manager = ["zypper"]
+//! interval = 1800
+//! error_interval = 300
+//! max_retries = 5
+//! format = " $icon $zypper.eng(w:1) updates available "
+//! format_singular = " $icon One update available "
+//! format_up_to_date = " $icon system up to date "
+//! [[block.click]]
+//! # shows dmenu with available updates. Any dmenu alternative should also work.
+//! button = "left"
+//! cmd = "zypper --quiet list-updates | dmenu -l 10"
+//! ```
+//!
 //! Multiple package managers config:
 //!
 //! Update the list of pending updates every thirty minutes (1800 seconds):
@@ -259,11 +279,11 @@
 //! ```toml
 //! [[block]]
 //! block = "packages"
-//! package_manager = ["apk", "apt", "aur", "brew", "dnf", "flatpak", "pacman", "snap", "xbps"]
+//! package_manager = ["apk", "apt", "aur", "brew", "dnf", "flatpak", "pacman", "snap", "xbps", "zypper"]
 //! interval = 1800
 //! error_interval = 300
 //! max_retries = 5
-//! format = " $icon $apk + $apt + $aur + $brew + $dnf + $flatpak + $pacman + $snap + $xbps = $total updates available "
+//! format = " $icon $apk + $apt + $aur + $brew + $dnf + $flatpak + $pacman + $snap + $xbps + $zypper = $total updates available "
 //! format_singular = " $icon One update available "
 //! format_up_to_date = " $icon system up to date "
 //! # If a linux update is available, but no ZFS package, it won't be possible to
@@ -302,6 +322,9 @@ use xbps::Xbps;
 pub mod snap;
 use snap::Snap;
 
+pub mod zypper;
+use zypper::Zypper;
+
 use regex::Regex;
 
 use super::prelude::*;
@@ -334,6 +357,7 @@ pub enum PackageManager {
     Pacman,
     Snap,
     Xbps,
+    Zypper,
 }
 
 impl PackageManager {
@@ -349,6 +373,7 @@ impl PackageManager {
             PackageManager::Pacman => "pacman",
             PackageManager::Snap => "snap",
             PackageManager::Xbps => "xbps",
+            PackageManager::Zypper => "zypper",
         }
     }
 
@@ -366,6 +391,7 @@ impl PackageManager {
             PackageManager::Pacman => Box::new(Pacman::new().await?),
             PackageManager::Snap => Box::new(Snap::new()),
             PackageManager::Xbps => Box::new(Xbps::new()),
+            PackageManager::Zypper => Box::new(Zypper::new()),
         })
     }
 }
@@ -405,6 +431,7 @@ pub async fn run(config: &Config, api: &CommonApi) -> Result<()> {
     check_manager!(PackageManager::Pacman);
     check_manager!(PackageManager::Snap);
     check_manager!(PackageManager::Xbps);
+    check_manager!(PackageManager::Zypper);
 
     let warning_updates_regex = config
         .warning_updates_regex
diff --git a/src/blocks/packages/zypper.rs b/src/blocks/packages/zypper.rs
new file mode 100644
index 000000000..e3e7a0010
--- /dev/null
+++ b/src/blocks/packages/zypper.rs
@@ -0,0 +1,38 @@
+use tokio::process::Command;
+
+use super::*;
+
+#[derive(Default)]
+pub struct Zypper;
+
+impl Zypper {
+    pub fn new() -> Self {
+        Default::default()
+    }
+}
+
+#[async_trait]
+impl Backend for Zypper {
+    fn name(&self) -> Cow<'static, str> {
+        "zypper".into()
+    }
+
+    async fn get_updates_list(&self) -> Result<Vec<String>> {
+        let stdout = Command::new("zypper")
+            .env("LC_ALL", "C")
+            .args(["--quiet", "list-updates"])
+            .output()
+            .await
+            .error("Failed to run `zypper list-updates`")?
+            .stdout;
+
+        let updates = String::from_utf8(stdout).error("zypper produced non-UTF8 output")?;
+        let updates_list: Vec<String> = updates
+            .lines()
+            .filter(|line| line.starts_with("v"))
+            .map(|line| line.to_string())
+            .collect();
+
+        Ok(updates_list)
+    }
+}
-- 
2.53.0

openSUSE Build Service is sponsored by