crabtalk_command/service/
linux.rs1use anyhow::Result;
4use wcore::paths::LOGS_DIR;
5
6pub const TEMPLATE: &str = include_str!("systemd.service");
8
9pub fn is_installed(label: &str) -> bool {
11 dirs::home_dir()
12 .map(|h| {
13 h.join(format!(".config/systemd/user/{label}.service"))
14 .exists()
15 })
16 .unwrap_or(false)
17}
18
19pub fn install(rendered: &str, label: &str) -> Result<()> {
21 let unit_name = format!("{label}.service");
22
23 let unit_dir = dirs::home_dir()
24 .ok_or_else(|| anyhow::anyhow!("cannot determine home directory"))?
25 .join(".config/systemd/user");
26 std::fs::create_dir_all(&unit_dir)?;
27 std::fs::create_dir_all(&*LOGS_DIR)?;
28
29 let unit_path = unit_dir.join(&unit_name);
30 std::fs::write(&unit_path, rendered)?;
31 println!("wrote {}", unit_path.display());
32
33 let status = std::process::Command::new("systemctl")
34 .args(["--user", "enable", "--now", &unit_name])
35 .status()?;
36 if status.success() {
37 println!("service enabled and started");
38 } else {
39 anyhow::bail!("systemctl enable failed (exit {})", status);
40 }
41 Ok(())
42}
43
44pub fn uninstall(label: &str) -> Result<()> {
46 let unit_name = format!("{label}.service");
47
48 let unit_path = dirs::home_dir()
49 .ok_or_else(|| anyhow::anyhow!("cannot determine home directory"))?
50 .join(".config/systemd/user")
51 .join(&unit_name);
52
53 if !unit_path.exists() {
54 anyhow::bail!("service not installed ({})", unit_path.display());
55 }
56
57 let status = std::process::Command::new("systemctl")
58 .args(["--user", "disable", "--now", &unit_name])
59 .status()?;
60 if !status.success() {
61 eprintln!("warning: systemctl disable exited with {}", status);
62 }
63
64 std::fs::remove_file(&unit_path)?;
65 println!("service uninstalled");
66 Ok(())
67}