oma-pm 0.63.0

APT package manager API abstraction library
Documentation
use crate::{apt::AptConfig, dbus::change_status};
use oma_apt::progress::DynInstallProgress;
use oma_utils::zbus;
use once_cell::sync::OnceCell;
use tokio::runtime::Runtime;
use zbus::Connection;

pub use oma_apt::util::{get_apt_progress_string, terminal_height, terminal_width};

#[derive(Default, Debug)]
pub struct NoProgress {
    _lastline: usize,
    _pulse_interval: usize,
    _disable: bool,
}

pub(crate) struct InstallProgressArgs {
    pub config: AptConfig,
    pub tokio: OnceCell<Runtime>,
    pub connection: OnceCell<Connection>,
}

pub(crate) struct OmaAptInstallProgress {
    config: AptConfig,
    tokio: OnceCell<Runtime>,
    connection: OnceCell<Connection>,
    pm: Box<dyn InstallProgressManager>,
}

pub trait InstallProgressManager {
    fn status_change(&self, pkgname: &str, steps_done: u64, total_steps: u64, config: &AptConfig);
    fn no_interactive(&self) -> bool;
    fn use_pty(&self) -> bool;
}

impl OmaAptInstallProgress {
    pub fn new(args: InstallProgressArgs, pm: Box<dyn InstallProgressManager>) -> Self {
        let InstallProgressArgs {
            config,
            tokio,
            connection,
        } = args;

        if pm.no_interactive() {
            unsafe { std::env::set_var("DEBIAN_FRONTEND", "noninteractive") };
        }

        if !pm.use_pty() {
            config.set("Dpkg::Use-Pty", "false");
        }

        Self {
            config,
            tokio,
            connection,
            pm,
        }
    }
}

impl DynInstallProgress for OmaAptInstallProgress {
    fn status_changed(
        &mut self,
        pkgname: String,
        steps_done: u64,
        total_steps: u64,
        _action: String,
    ) {
        let conn = &self.connection;

        self.pm
            .status_change(&pkgname, steps_done, total_steps, &self.config);

        if let Some(tokio) = self.tokio.get()
            && let Some(conn) = conn.get()
        {
            tokio.block_on(async move {
                change_status(conn, &format!("i {pkgname}")).await.ok();
            });
        }
    }

    fn error(&mut self, _pkgname: String, _steps_done: u64, _total_steps: u64, _error: String) {}
}