pacaptr/pm/
tlmgr.rs

1#![doc = doc_self!()]
2
3use std::sync::LazyLock;
4
5use async_trait::async_trait;
6use indoc::indoc;
7use tap::prelude::*;
8
9use super::{DryRunStrategy, Pm, PmHelper, Strategy};
10use crate::{config::Config, error::Result, exec::Cmd};
11
12macro_rules! doc_self {
13    () => {
14        indoc! {"
15            The [TexLive Package Manager](https://www.tug.org/texlive/tlmgr.html).
16        "}
17    };
18}
19use doc_self;
20
21#[doc = doc_self!()]
22#[derive(Debug)]
23pub struct Tlmgr {
24    cfg: Config,
25}
26
27static STRAT_CHECK_DRY: LazyLock<Strategy> = LazyLock::new(|| Strategy {
28    dry_run: DryRunStrategy::with_flags(["--dry-run"]),
29    ..Strategy::default()
30});
31
32impl Tlmgr {
33    #[must_use]
34    #[allow(missing_docs)]
35    pub const fn new(cfg: Config) -> Self {
36        Self { cfg }
37    }
38}
39
40#[async_trait]
41impl Pm for Tlmgr {
42    /// Gets the name of the package manager.
43    fn name(&self) -> &'static str {
44        "tlmgr"
45    }
46
47    fn cfg(&self) -> &Config {
48        &self.cfg
49    }
50
51    /// Q generates a list of installed packages.
52    async fn q(&self, kws: &[&str], flags: &[&str]) -> Result<()> {
53        self.qi(kws, flags).await
54    }
55
56    /// Qi displays local package information: name, version, description, etc.
57    async fn qi(&self, kws: &[&str], flags: &[&str]) -> Result<()> {
58        Cmd::new(["tlmgr", "info", "--only-installed"])
59            .kws(kws)
60            .flags(flags)
61            .pipe(|cmd| self.run(cmd))
62            .await
63    }
64
65    /// Qk verifies one or more packages.
66    async fn qk(&self, _kws: &[&str], flags: &[&str]) -> Result<()> {
67        self.run(Cmd::new(["tlmgr", "check", "files"]).flags(flags))
68            .await
69    }
70
71    /// Ql displays files provided by local package.
72    async fn ql(&self, kws: &[&str], flags: &[&str]) -> Result<()> {
73        Cmd::new(["tlmgr", "info", "--only-installed", "--list"])
74            .kws(kws)
75            .flags(flags)
76            .pipe(|cmd| self.run(cmd))
77            .await
78    }
79
80    /// R removes a single package, leaving all of its dependencies installed.
81    async fn r(&self, kws: &[&str], flags: &[&str]) -> Result<()> {
82        Cmd::new(["tlmgr", "remove"])
83            .kws(kws)
84            .flags(flags)
85            .pipe(|cmd| self.run_with(cmd, self.default_mode(), &STRAT_CHECK_DRY))
86            .await
87    }
88
89    /// S installs one or more packages by name.
90    async fn s(&self, kws: &[&str], flags: &[&str]) -> Result<()> {
91        Cmd::new(["tlmgr", "install"])
92            .kws(kws)
93            .flags(flags)
94            .pipe(|cmd| self.run_with(cmd, self.default_mode(), &STRAT_CHECK_DRY))
95            .await
96    }
97
98    /// Si displays remote package information: name, version, description, etc.
99    async fn si(&self, kws: &[&str], flags: &[&str]) -> Result<()> {
100        self.run(Cmd::new(["tlmgr", "info"]).kws(kws).flags(flags))
101            .await
102    }
103
104    /// Sl displays a list of all packages in all installation sources that are
105    /// handled by the package management.
106    async fn sl(&self, _kws: &[&str], flags: &[&str]) -> Result<()> {
107        self.run(Cmd::new(["tlmgr", "info"]).flags(flags)).await
108    }
109
110    /// Ss searches for package(s) by searching the expression in name,
111    /// description, short description.
112    async fn ss(&self, kws: &[&str], flags: &[&str]) -> Result<()> {
113        Cmd::new(["tlmgr", "search", "--global"])
114            .kws(kws)
115            .flags(flags)
116            .pipe(|cmd| self.run(cmd))
117            .await
118    }
119
120    /// Su updates outdated packages.
121    async fn su(&self, kws: &[&str], flags: &[&str]) -> Result<()> {
122        Cmd::new(if kws.is_empty() {
123            &["tlmgr", "update", "--self", "--all"][..]
124        } else {
125            &["tlmgr", "update", "--self"][..]
126        })
127        .kws(kws)
128        .flags(flags)
129        .pipe(|cmd| self.run_with(cmd, self.default_mode(), &STRAT_CHECK_DRY))
130        .await
131    }
132
133    /// Suy refreshes the local package database, then updates outdated
134    /// packages.
135    async fn suy(&self, kws: &[&str], flags: &[&str]) -> Result<()> {
136        self.su(kws, flags).await
137    }
138
139    /// U upgrades or adds package(s) to the system and installs the required
140    /// dependencies from sync repositories.
141    async fn u(&self, kws: &[&str], flags: &[&str]) -> Result<()> {
142        Cmd::new(["tlmgr", "install", "--file"])
143            .kws(kws)
144            .flags(flags)
145            .pipe(|cmd| self.run_with(cmd, self.default_mode(), &STRAT_CHECK_DRY))
146            .await
147    }
148}