#![doc = doc_self!()]
use std::sync::LazyLock;
use async_trait::async_trait;
use indoc::indoc;
use tap::prelude::*;
use super::{NoCacheStrategy, Pm, PmHelper, PromptStrategy, Strategy};
use crate::{config::Config, error::Result, exec::Cmd};
macro_rules! doc_self {
() => {
indoc! {"
The [Advanced Package Tool](https://salsa.debian.org/apt-team/apt).
"}
};
}
use doc_self;
#[doc = doc_self!()]
#[derive(Debug)]
pub struct Apt {
cfg: Config,
}
static STRAT_PROMPT: LazyLock<Strategy> = LazyLock::new(|| Strategy {
prompt: PromptStrategy::native_no_confirm(["--yes"]),
..Strategy::default()
});
static STRAT_INSTALL: LazyLock<Strategy> = LazyLock::new(|| Strategy {
prompt: PromptStrategy::native_no_confirm(["--yes"]),
no_cache: NoCacheStrategy::Scc,
..Strategy::default()
});
impl Apt {
#[must_use]
#[allow(missing_docs)]
pub const fn new(cfg: Config) -> Self {
Self { cfg }
}
#[must_use]
fn cmd(&self) -> &str {
self.cfg
.default_pm
.as_deref()
.expect("default package manager should have been assigned before initialization")
}
}
#[async_trait]
impl Pm for Apt {
fn name(&self) -> &'static str {
"apt"
}
fn cfg(&self) -> &Config {
&self.cfg
}
async fn q(&self, kws: &[&str], flags: &[&str]) -> Result<()> {
Cmd::new(["apt", "list", "--installed"])
.kws(kws)
.flags(flags)
.pipe(|cmd| self.run(cmd))
.await
}
async fn qc(&self, kws: &[&str], flags: &[&str]) -> Result<()> {
self.run(Cmd::new(["apt", "changelog"]).kws(kws).flags(flags))
.await
}
async fn qe(&self, kws: &[&str], flags: &[&str]) -> Result<()> {
self.run(Cmd::new(["apt-mark", "showmanual"]).kws(kws).flags(flags))
.await
}
async fn qi(&self, kws: &[&str], flags: &[&str]) -> Result<()> {
self.run(Cmd::new(["dpkg-query", "-s"]).kws(kws).flags(flags))
.await
}
async fn qii(&self, kws: &[&str], flags: &[&str]) -> Result<()> {
self.sii(kws, flags).await
}
async fn qo(&self, kws: &[&str], flags: &[&str]) -> Result<()> {
self.run(Cmd::new(["dpkg-query", "-S"]).kws(kws).flags(flags))
.await
}
async fn qp(&self, kws: &[&str], flags: &[&str]) -> Result<()> {
self.run(Cmd::new(["dpkg-deb", "-I"]).kws(kws).flags(flags))
.await
}
async fn qs(&self, kws: &[&str], flags: &[&str]) -> Result<()> {
Cmd::new(["dpkg-query", "-l"])
.flags(flags)
.pipe(|cmd| self.search_regex_with_header(cmd, kws, 4))
.await
}
async fn qu(&self, kws: &[&str], flags: &[&str]) -> Result<()> {
Cmd::with_sudo(["apt", "upgrade", "--trivial-only"])
.kws(kws)
.flags(flags)
.pipe(|cmd| self.run(cmd))
.await
}
async fn r(&self, kws: &[&str], flags: &[&str]) -> Result<()> {
Cmd::with_sudo(["apt", "remove"])
.kws(kws)
.flags(flags)
.pipe(|cmd| self.run_with(cmd, self.default_mode(), &STRAT_PROMPT))
.await
}
async fn rn(&self, kws: &[&str], flags: &[&str]) -> Result<()> {
Cmd::with_sudo(["apt", "purge"])
.kws(kws)
.flags(flags)
.pipe(|cmd| self.run_with(cmd, self.default_mode(), &STRAT_PROMPT))
.await
}
async fn rns(&self, kws: &[&str], flags: &[&str]) -> Result<()> {
Cmd::with_sudo(["apt", "autoremove", "--purge"])
.kws(kws)
.flags(flags)
.pipe(|cmd| self.run_with(cmd, self.default_mode(), &STRAT_PROMPT))
.await
}
async fn rs(&self, kws: &[&str], flags: &[&str]) -> Result<()> {
Cmd::with_sudo(["apt", "autoremove"])
.kws(kws)
.flags(flags)
.pipe(|cmd| self.run_with(cmd, self.default_mode(), &STRAT_PROMPT))
.await
}
async fn s(&self, kws: &[&str], flags: &[&str]) -> Result<()> {
if self.cfg.needed {
Cmd::with_sudo(&[self.cmd(), "install"][..])
} else {
Cmd::with_sudo(&[self.cmd(), "install", "--reinstall"][..])
}
.kws(kws)
.flags(flags)
.pipe(|cmd| self.run_with(cmd, self.default_mode(), &STRAT_INSTALL))
.await
}
async fn sc(&self, kws: &[&str], flags: &[&str]) -> Result<()> {
Cmd::with_sudo(["apt", "clean"])
.kws(kws)
.flags(flags)
.pipe(|cmd| self.run_with(cmd, self.default_mode(), &STRAT_PROMPT))
.await
}
async fn scc(&self, kws: &[&str], flags: &[&str]) -> Result<()> {
Cmd::with_sudo(["apt", "autoclean"])
.kws(kws)
.flags(flags)
.pipe(|cmd| self.run_with(cmd, self.default_mode(), &STRAT_PROMPT))
.await
}
async fn sg(&self, kws: &[&str], flags: &[&str]) -> Result<()> {
Cmd::new(if kws.is_empty() {
["tasksel", "--list-task"]
} else {
["tasksel", "--task-packages"]
})
.kws(kws)
.flags(flags)
.pipe(|cmd| self.run(cmd))
.await
}
async fn si(&self, kws: &[&str], flags: &[&str]) -> Result<()> {
self.run(Cmd::new(["apt", "show"]).kws(kws).flags(flags))
.await
}
async fn sii(&self, kws: &[&str], flags: &[&str]) -> Result<()> {
self.run(Cmd::new(["apt", "rdepends"]).kws(kws).flags(flags))
.await
}
async fn ss(&self, kws: &[&str], flags: &[&str]) -> Result<()> {
self.run(Cmd::new([self.cmd(), "search"]).kws(kws).flags(flags))
.await
}
async fn su(&self, kws: &[&str], flags: &[&str]) -> Result<()> {
if kws.is_empty() {
Cmd::with_sudo(["apt", "upgrade"])
.flags(flags)
.pipe(|cmd| self.run_with(cmd, self.default_mode(), &STRAT_PROMPT))
.await?;
Cmd::with_sudo(["apt", "dist-upgrade"])
.flags(flags)
.pipe(|cmd| self.run_with(cmd, self.default_mode(), &STRAT_INSTALL))
.await
} else {
self.s(kws, flags).await
}
}
async fn suy(&self, kws: &[&str], flags: &[&str]) -> Result<()> {
self.sy(&[], flags).await?;
self.su(kws, flags).await
}
async fn sw(&self, kws: &[&str], flags: &[&str]) -> Result<()> {
Cmd::with_sudo([self.cmd(), "install", "--download-only"])
.kws(kws)
.flags(flags)
.pipe(|cmd| self.run_with(cmd, self.default_mode(), &STRAT_INSTALL))
.await
}
async fn sy(&self, kws: &[&str], flags: &[&str]) -> Result<()> {
self.run(Cmd::with_sudo([self.cmd(), "update"]).flags(flags))
.await?;
if !kws.is_empty() {
self.s(kws, flags).await?;
}
Ok(())
}
}