#![doc = doc_self!()]
use std::sync::LazyLock;
use async_trait::async_trait;
use indoc::indoc;
use tap::prelude::*;
use super::{Pm, PmHelper, PromptStrategy, Strategy};
use crate::{
config::Config,
error::{Error, Result},
exec::Cmd,
};
macro_rules! doc_self {
() => {
indoc! {"
The [Python Package Installer](https://pip.pypa.io/).
"}
};
}
use doc_self;
#[doc = doc_self!()]
#[derive(Debug)]
pub struct Pip {
cfg: Config,
}
static STRAT_PROMPT: LazyLock<Strategy> = LazyLock::new(|| Strategy {
prompt: PromptStrategy::CustomPrompt,
..Strategy::default()
});
static STRAT_UNINSTALL: LazyLock<Strategy> = LazyLock::new(|| Strategy {
prompt: PromptStrategy::native_no_confirm(["-y"]),
..Strategy::default()
});
impl Pip {
#[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 Pip {
fn name(&self) -> &'static str {
"pip"
}
fn cfg(&self) -> &Config {
&self.cfg
}
async fn q(&self, kws: &[&str], flags: &[&str]) -> Result<()> {
if kws.is_empty() {
self.run(Cmd::new([self.cmd(), "list"]).flags(flags)).await
} else {
self.qs(kws, flags).await
}
}
async fn qi(&self, kws: &[&str], flags: &[&str]) -> Result<()> {
self.run(Cmd::new([self.cmd(), "show"]).kws(kws).flags(flags))
.await
}
async fn qs(&self, kws: &[&str], flags: &[&str]) -> Result<()> {
self.search_regex(Cmd::new([self.cmd(), "list"]).flags(flags), kws)
.await
}
async fn qu(&self, kws: &[&str], flags: &[&str]) -> Result<()> {
Cmd::new([self.cmd(), "list", "--outdated"])
.kws(kws)
.flags(flags)
.pipe(|cmd| self.run(cmd))
.await
}
async fn r(&self, kws: &[&str], flags: &[&str]) -> Result<()> {
Cmd::new([self.cmd(), "uninstall"])
.kws(kws)
.flags(flags)
.pipe(|cmd| self.run_with(cmd, self.default_mode(), &STRAT_UNINSTALL))
.await
}
async fn s(&self, kws: &[&str], flags: &[&str]) -> Result<()> {
Cmd::new([self.cmd(), "install"])
.kws(kws)
.flags(flags)
.pipe(|cmd| self.run_with(cmd, self.default_mode(), &STRAT_PROMPT))
.await
}
async fn sc(&self, _kws: &[&str], flags: &[&str]) -> Result<()> {
self.run(Cmd::new([self.cmd(), "cache", "purge"]).flags(flags))
.await
}
async fn su(&self, kws: &[&str], flags: &[&str]) -> Result<()> {
if kws.is_empty() {
return Err(Error::OperationUnimplementedError {
op: "su".into(),
pm: self.name().into(),
});
}
Cmd::new([self.cmd(), "install", "--upgrade"])
.kws(kws)
.flags(flags)
.pipe(|cmd| self.run(cmd))
.await
}
async fn sw(&self, kws: &[&str], flags: &[&str]) -> Result<()> {
Cmd::new([self.cmd(), "download"])
.kws(kws)
.flags(flags)
.pipe(|cmd| self.run(cmd))
.await
}
}