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 fn name(&self) -> &'static str {
44 "tlmgr"
45 }
46
47 fn cfg(&self) -> &Config {
48 &self.cfg
49 }
50
51 async fn q(&self, kws: &[&str], flags: &[&str]) -> Result<()> {
53 self.qi(kws, flags).await
54 }
55
56 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 async fn qk(&self, _kws: &[&str], flags: &[&str]) -> Result<()> {
67 self.run(Cmd::new(["tlmgr", "check", "files"]).flags(flags))
68 .await
69 }
70
71 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 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 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 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 async fn sl(&self, _kws: &[&str], flags: &[&str]) -> Result<()> {
107 self.run(Cmd::new(["tlmgr", "info"]).flags(flags)).await
108 }
109
110 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 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 async fn suy(&self, kws: &[&str], flags: &[&str]) -> Result<()> {
136 self.su(kws, flags).await
137 }
138
139 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}